﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TAS;
using OMS;
using System.Threading;
using Onixs.CmeFastHandler;

namespace Algo
{
    public class TradeThreadArgs
    {
       public Trade trade;
       public AlgoEngine algo;
    }

    public class AlgoEngine
    {
        protected static log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        bool exitTradeProcessingThread = false, exitStatusProcessingThread = false;

        public TASEngine tasEngine = new TASEngine();
        public OMSEngine omsEngine = new OMSEngine();        

        List<Trade> fMMTradeBook = new List<Trade>();
        List<Trade> sMMTradeBook = new List<Trade>();
        List<Trade> sprMMTradeBook = new List<Trade>();
        List<Trade> fsHTradeBook = new List<Trade>();
        List<Trade> fsSprTradeBook = new List<Trade>();
        List<Trade> tradeBookClosed = new List<Trade>();
        List<Trade> tradeBookCancelled = new List<Trade>();

        public double tradeIDcount = 1000001; // added by MS 
        
        private Thread tradeProcessingThread = null, statusProcessingThread = null;
        private ManualResetEvent tasInterruptEvent = new ManualResetEvent(false), omsInterruptEvent = new ManualResetEvent(false);

        List<Order> orderQueue = new List<Order>();

        public DateTime simulationStartTime { get; set; }
        public DateTime simulationEndTime { get; set; }
        public bool simulation { get; set; }

        public bool tradeCreated = false;

        public delegate void LogMessageHandler (string message);
        public event LogMessageHandler OnLogMessageHandler;

        public delegate void TradeDataUpdate(double tradeId, int type, string status, double netGain);
        public event TradeDataUpdate OnTradeDataUpdate;

        public delegate void OrderUpdate(string orderID, double tradeId, string securityID, string type, double price, string status);
        public event OrderUpdate OnOrderUpdate;

        public void Initialize()
        {
            //log.Info("Hello World, I am MBX");
            System.Diagnostics.Trace.WriteLine("MBX Update: Hello World, I am MBX");

            OnLogMessageHandler("Start Music");

            // Initialize engines
            omsEngine.Initialize(tasEngine.securityEntityMap);
            omsEngine.InterruptEvent = omsInterruptEvent;
            omsEngine.orderQueue = orderQueue;
            omsEngine.InterruptEvent.Reset();
            omsEngine.Connect();
            
            if (simulation == true)
            {
                tasEngine.simulation = simulation;
                tasEngine.simulationStartTime = simulationStartTime;
                tasEngine.simulationEndTime = simulationEndTime;
            }

            tasEngine.Initialize();
            tasEngine.OnTradeRecievedHandler += new TASEngine.OrderTradeRecievedHandler(OnTradeRecievedHandler);

            // proceed only after receiving all 3 security definitions.

            ThreadStart tasThread = new ThreadStart(ProcessTASData);

            if (tasThread != null)
            {
                tradeProcessingThread = new Thread(tasThread);
                tradeProcessingThread.Name = "TAS Process Thread";
                tradeProcessingThread.SetApartmentState(ApartmentState.MTA);
                tradeProcessingThread.Priority = ThreadPriority.Normal;
                tradeProcessingThread.Start();
            }

            ThreadStart omsThread = new ThreadStart(ProcessOMSData);

            if (omsThread != null)
            {
                statusProcessingThread = new Thread(omsThread);
                statusProcessingThread.Name = "OMS Process Thread";
                statusProcessingThread.SetApartmentState(ApartmentState.MTA);
                statusProcessingThread.Priority = ThreadPriority.Normal;
                statusProcessingThread.Start();
            }
        }

        // The arguements for this function can be modified to meet the algo's 
        // requirement

        // for buy
        public Order CreateOrder(double tradeID, string securityDesc, double quantity, Order.OrderType ordertype) 
        {
            //System.Diagnostics.Trace.WriteLine("MBX Update: Buy order created");
            Order order = omsEngine.Buy(tradeID, securityDesc, quantity, ordertype);
            order.originalQuantity = order.quantity;

            OnOrderUpdate(order.OrderID, tradeID, securityDesc, "Buy", 0, "Created");
            return order;
        }
       
        // for sell
        public Order CreateOrder(double tradeID, double quantity, string securityDesc, Order.OrderType ordertype) 
        {
            OnLogMessageHandler("Sell order created");

           // System.Diagnostics.Trace.WriteLine("MBX Update: Sell order created");
            Order order= omsEngine.Sell(tradeID, quantity, securityDesc, ordertype);
            order.originalQuantity = order.quantity;

            OnOrderUpdate(order.OrderID, tradeID, securityDesc, "Sell", 0, "Created");

            return order;
        }

        public void ShutDown()
        {
            // Clean up all memory, threads and objects created.
            
            exitTradeProcessingThread = true;
            Thread.Sleep(1000);
            tradeProcessingThread = null;

            // Close All Engines
            omsEngine.Disconnect();

            omsEngine = null;
            tasEngine = null;
            
            omsInterruptEvent = null;
            tasInterruptEvent = null;
        }

        // this thread creates trades
        [MTAThread]
        private void ProcessTASData()
        {
            while (true)
            {
                Thread.Sleep(0);
                
                if (tasEngine.firstLeg != null && tasEngine.secondLeg != null && tasEngine.spread != null)
                {
                    if (tasEngine.firstLeg.securityStatus == SecurityStatus.ReadyToTrade && tasEngine.secondLeg.securityStatus == SecurityStatus.ReadyToTrade && tasEngine.spread.securityStatus == SecurityStatus.ReadyToTrade)
                    {
                        while (exitTradeProcessingThread == false)
                        {
                            Thread.Sleep(0);

                            while (tasEngine.booksReadyToTrade == false)
                            {
                                Thread.Sleep(0);
                            }

                            // tasInterruptEvent.WaitOne(1000);

                            // create trades

                            //type 1
                            #region
                            if (fMMTradeBook.Count() == 0)
                            {
                                //Console.WriteLine(tasEngine.firstLeg.netPosition.ToString() + " - " + tasEngine.firstLeg.netValue.ToString());
                                // try to create 2 trades
                              // CreateTrade(1, 1, 4, 1, 1);
                             //   CreateTrade(1, 1, 4, 1, 2);
                                
                            }
                            else if (fMMTradeBook.Count() == 1)
                            {
                                // try to create 1 trade of the opposite side
                                if (fMMTradeBook[0].initiateLeg == 1)
                                {
                                    // try to create a sell side trade
                                    CreateTrade(1, 1, 4, 1, 2);
                                }
                                else
                                {
                                    // try to create a buy side trade
                                    CreateTrade(1, 1, 4, 1, 1);
                                }
                            }
                            #endregion

                            //type 2
                            #region
                            if (sMMTradeBook.Count() == 0)
                                {
                                    // try to create 2 trades
                                   // Console.WriteLine(tasEngine.firstLeg.netPosition.ToString() + " - " + tasEngine.firstLeg.netValue.ToString());
                                   // CreateTrade(2, 1, 4, 1, 1);
                                    // CreateTrade(2, 1, 4, 1, 2);
                                }
                            else if (sMMTradeBook.Count() == 1)
                            {
                                /*
                                // try to create 1 trade of the opposite side
                                if (sMMTradeBook[0].initiateLeg == 1)
                                {
                                    // try to create a sell side trade
                                    CreateTrade(2, 1, 4, 1, 2);
                                }
                                else
                                {
                                    // try to create a buy side trade
                                    CreateTrade(2, 1, 4, 1, 1);
                                }
                              */
                            }
                            
                            #endregion

                            //type 3
                            #region
                            if (sprMMTradeBook.Count() == 0)
                            {
                                // try to create 2 trades
                            }
                            else if (sprMMTradeBook.Count() == 1)
                            {
                                // try to create 1 trade of the opposite side
                                if (sprMMTradeBook[0].initiateLeg == 1)
                                {
                                    // try to create a sell side trade
                                }
                                else
                                {
                                    // try to create a buy side trade
                                }
                            }
                            #endregion

                            //type 4
                            #region
                            if (fsHTradeBook.Count() == 0)
                            {
                                // try to create 2 trades
                            }
                            else if (fsHTradeBook.Count() == 1)
                            {
                                // try to create 1 trade of the opposite side
                                if (fsHTradeBook[0].initiateLeg == 1)
                                {
                                    // try to create a sell side trade
                                }
                                else
                                {
                                    // try to create a buy side trade
                                }
                            }
                            #endregion

                            //type 5
                            #region
                            if (fsSprTradeBook.Count() == 0)
                            {
                                // try to create 2 trades
                               Console.WriteLine(tasEngine.firstLeg.netPosition.ToString() + " - " + tasEngine.secondLeg.netPosition.ToString() + " - " + tasEngine.spread.netPosition.ToString() + " - " + (tasEngine.firstLeg.netValue + tasEngine.secondLeg.netValue + tasEngine.spread.netValue).ToString());
                              CreateTrade(5, 1, 3, 1, 1);
                              //  CreateTrade(5, 1, 2, 1, 2);
                            }
                            else if (fsSprTradeBook.Count() == 1)
                            {
                                /*
                                // try to create 1 trade of the opposite side
                                if (fsSprTradeBook[0].initiateLeg == 1)
                                {
                                    // try to create a sell side trade
                                    //CreateTrade(5, 1, 2, 1, 2);
                                }
                                else
                                {
                                    // try to create a buy side trade
                                   // CreateTrade(5, 1, 2, 1, 1);
                                }
                                */
                            }
                            #endregion
                        }
                    }
                }
            }
        }

        void OnTradeRecievedHandler(TradeDataEntity tradeDataEntity)
        {
            OrderBook orderBook = omsEngine.tradingManager.orderBook;
            string key = null;
            Order order;

            foreach (var item in orderBook.clientOrderID2order)
            {
                order = item.Value;
                key = null;

                if (order.SecurityID == tradeDataEntity.SecurityID)
                {
                    if (order.Side == Order.OrderSide.Buy)
                    {
                        if (order.Price >= tradeDataEntity.Price || ((order.Price >= tradeDataEntity.bestAsk.Price)&&(!tradeDataEntity.isTrade)))
                        {
                            order.filledQuantity = order.quantity;
                            order.Status = Order.OrderStatus.Fill;
                            order.lastFillPrice = order.Price;
                            foreach (var item1 in tasEngine.securityEntityMap)
                            {
                                if (item1.Value.ID == order.SecurityID)
                                {
                                    item1.Value.netPosition = item1.Value.netPosition + order.quantity;
                                    item1.Value.netValue = item1.Value.netValue - ((long)order.quantity * order.Price * 10);
                                }
                            }
                            key = item.Key;
                            System.Diagnostics.Trace.WriteLine("MBX Update: FILL" + ";" + order.tradeID + ";" + order.ClientOrderID + ";" + order.Status + ";" + DateTime.Now + ";" + order.quantity + ";" + order.filledQuantity + ";" + order.Symbol + ";" + order.Price + ";" + order.Side + ";" + order.ToString());
                            // System.Diagnostics.Trace.WriteLine("ANALYSIS : FILL " + order.tradeID + " : " + order.Side + " : " + order.Price);
                            break;
                        }
                    }
                    if (order.Side == Order.OrderSide.Sell)
                    {
                        if (order.Price <= tradeDataEntity.Price || ((order.Price <= tradeDataEntity.bestBid.Price)&&(!tradeDataEntity.isTrade)))
                        {
                            order.filledQuantity = order.quantity;
                            order.Status = Order.OrderStatus.Fill;
                            order.lastFillPrice = order.Price;
                            foreach (var item1 in tasEngine.securityEntityMap)
                            {
                                if (item1.Value.ID == order.SecurityID)
                                {
                                    item1.Value.netPosition = item1.Value.netPosition - order.quantity;
                                    item1.Value.netValue = item1.Value.netValue + ((long)order.quantity * order.Price * 10);
                                }
                            }
                            key = item.Key;
                            System.Diagnostics.Trace.WriteLine("MBX Update: FILL" + ";" + order.tradeID + ";" + order.ClientOrderID + ";" + order.Status + ";" + DateTime.Now + ";" + order.quantity + ";" + order.filledQuantity + ";" + order.Symbol + ";" + order.Price + ";" + order.Side + ";" + order.ToString());
                            // System.Diagnostics.Trace.WriteLine("ANALYSIS : FILL " + order.tradeID + " : " + order.Side + " : " + order.Price);
                            break;
                        }
                    }
                }
            }

            if (key != null)
            {
                orderBook.clientOrderID2order.Remove(key);
            }
        }

        // initiade side : 1 - Buy; 2 - Sell;
        private void CreateTrade(int tradeType, int quantity, long ticks, int initiateLeg, int initiateSide)
        {
            if (tradeCreated == true)
            {
                return;
            }

            tradeCreated = true;

            // if book.bestoffer of CLM2 - book.bestbid of CLN2 - book.bestbid of CLM2-CLN2 is <= 2
            // else if book.bestbid of CLM2 - book.bestoffer of CLN2 + book.bestoffer of CLM2-CLN2 is >= 2
            // create trade of type 5 and send market orders of all 3 legs.
            
            // create the trade of type 5
            Trade trade = new Trade();
            trade.CreateTrade(tradeType, quantity, ticks, initiateSide, tradeIDcount++);
            trade.initiateLeg = initiateLeg;
            trade.createTime = DateTime.Now;
            
            // to create trade of type 1 - buy side
            // read last 1 min ohlc, bollinger bands

            if (tradeType == 1)
                fMMTradeBook.Add(trade);
            else if (tradeType == 2)
                sMMTradeBook.Add(trade);
            else if (tradeType == 3)
                sprMMTradeBook.Add(trade);
            else if (tradeType == 4)
                fsHTradeBook.Add(trade);
            else if (tradeType == 5)
                fsSprTradeBook.Add(trade);

            OnTradeDataUpdate(trade.tradeID, trade.tradeType, "Created", 0);

            System.Diagnostics.Trace.WriteLine("MBX Update: Created" + ";" + trade.tradeID + ";" + trade.status +";" + trade.createTime + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide);

            // create the thread that will execute the trade and pass the trade to the thread
            Thread executeTrade = new Thread(AlgoEngine.execute);
            executeTrade.Name = "Executing Trade ID: " + trade.tradeID;
            TradeThreadArgs args = new TradeThreadArgs();
            args.trade = trade;
            args.algo = this;
            executeTrade.Start(args);

            System.Diagnostics.Trace.WriteLine("MBX Update: Started" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide);
            
        }
        
        public static void execute(object parameter)
        {
            try
            {
                TradeThreadArgs args = (TradeThreadArgs)parameter;
                Trade trade = args.trade;
                AlgoEngine algo = args.algo;

                algo.OnLogMessageHandler("Thread created");

               
                // creating orders
                trade.order1b = algo.CreateOrder(trade.tradeID, algo.tasEngine.fl, trade.initiateQuantity, Order.OrderType.Limit);
                trade.order1s = algo.CreateOrder(trade.tradeID, trade.initiateQuantity, algo.tasEngine.fl, Order.OrderType.Limit);
                trade.order2b = algo.CreateOrder(trade.tradeID, algo.tasEngine.sl, trade.initiateQuantity, Order.OrderType.Limit);
                trade.order2s = algo.CreateOrder(trade.tradeID, trade.initiateQuantity, algo.tasEngine.sl, Order.OrderType.Limit);
                trade.order3b = algo.CreateOrder(trade.tradeID, algo.tasEngine.spr, trade.initiateQuantity, Order.OrderType.Limit);
                trade.order3s = algo.CreateOrder(trade.tradeID, trade.initiateQuantity, algo.tasEngine.spr, Order.OrderType.Limit);
                trade.order1bb = algo.CreateOrder(trade.tradeID, algo.tasEngine.fl, 1, Order.OrderType.Limit);
                trade.order1ss = algo.CreateOrder(trade.tradeID, 1, algo.tasEngine.fl, Order.OrderType.Limit);
                trade.order2bb = algo.CreateOrder(trade.tradeID, algo.tasEngine.sl, 1, Order.OrderType.Limit);
                trade.order2ss = algo.CreateOrder(trade.tradeID, 1, algo.tasEngine.sl, Order.OrderType.Limit);
                trade.order3bb = algo.CreateOrder(trade.tradeID, algo.tasEngine.spr, 1, Order.OrderType.Limit);
                trade.order3ss = algo.CreateOrder(trade.tradeID, 1, algo.tasEngine.spr, Order.OrderType.Limit);

                TimeSpan createdAge;
                TimeSpan initiatedAge;

                long dtemp1, lClosest50_1;
                long dtemp2;
                long dtemp3, lClosest50_2;
                long dtemp4;

                BollingerEntity betemp1;
                BollingerEntity betemp2;
                BollingerEntity betemp3;

                OHLCEntity ohlctemp1;
                OHLCEntity ohlctemp2;
                OHLCEntity ohlctemp3;

                System.Diagnostics.Trace.WriteLine("MBX Update: Executing" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide);

                while (trade.status != 5 && trade.status != 7)
                {
                    Thread.Sleep(0);

                    createdAge = DateTime.Now.Subtract(trade.createTime);
                    initiatedAge = DateTime.Now.Subtract(trade.initiateTime);

                    dtemp1 = 0;
                    dtemp2 = 0;
                    dtemp3 = 0;
                    dtemp4 = 0;
                    
                    // reduce the number of checks in this if
                    if (trade.order1b != null && trade.order1s != null && trade.order2b != null && trade.order2s != null && trade.order3b != null && trade.order3s != null)
                    {
                        trade.fPos = trade.order1b.filledQuantity - trade.order1s.filledQuantity + trade.order1bb.filledQuantity - trade.order1ss.filledQuantity;
                        trade.sPos = trade.order2b.filledQuantity - trade.order2s.filledQuantity + trade.order2bb.filledQuantity - trade.order2ss.filledQuantity;
                        trade.sprPos = trade.order3b.filledQuantity - trade.order3s.filledQuantity + trade.order3bb.filledQuantity - trade.order3ss.filledQuantity;
                    }
                    
                                      
                    if (trade.tradeType == 5)
                    #region
                    {
                        // for trade type 5, do the following
                        if (trade.status == 1)
                        {
                            // trade is newly generated. create orders here. place orders. if orders are accepted change status to 2

                            #region
                            if (trade.initiateSide == 1) // buy
                            {

                                if (trade.order1b.Status == Order.OrderStatus.PendingNew && trade.order2s.Status == Order.OrderStatus.PendingNew && trade.order3s.Status == Order.OrderStatus.PendingNew)
                                {
                                    trade.p2s = (long)algo.tasEngine.secondLeg.bestBid.Price;
                                    trade.p3s = (long)algo.tasEngine.spread.bestBid.Price;
                                    trade.p1b = trade.p2s + trade.p3s - trade.ticks;
                                    trade.p1s = trade.p1b + 3;

                                    trade.order1b.Price = trade.p1b;
                                    algo.omsEngine.tradingManager.SendNewOrder(trade.order1b);

                                }
                                else
                                {
                                    trade.status = 2;
                                    System.Diagnostics.Trace.WriteLine("MBX Update: Initiating" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide);

                                }                                
                            }
                            else //sell
                            {
                               
                                if (trade.order1s.Status == Order.OrderStatus.New && trade.order2b.Status == Order.OrderStatus.New && trade.order3b.Status == Order.OrderStatus.New)
                                {
                                    if ((algo.tasEngine.firstLeg.bestBid.Price - algo.tasEngine.secondLeg.bestAsk.Price - algo.tasEngine.spread.bestAsk.Price) > trade.ticks)
                                    {
                                        trade.order1s.Price = (long)algo.tasEngine.firstLeg.bestAsk.Price - 1;
                                        trade.order2b.Price = (long)algo.tasEngine.secondLeg.bestBid.Price + 1;
                                        trade.order3b.Price = (long)algo.tasEngine.spread.bestBid.Price + 1;
                                        algo.omsEngine.tradingManager.SendNewOrder(trade.order1s);
                                    }
                                }
                                else
                                {
                                    trade.status = 2;
                                    System.Diagnostics.Trace.WriteLine("MBX Update: Initiating" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide);

                                }
                                 
                            }
                            #endregion
                        }
                        if (trade.status == 2)
                        {
                            // orders placed and working.
                            // check if all orders are still working. 
                            // if yes, modify / monitor. if no, set initiate leg, unhedged quantities and change status to 3
                            // handle partially filled orders.

                            // Auto - Spreader for working orders. Ignoring the quantity complexity for the time being
                            // buy
                            #region
                            if (trade.initiateSide == 1)
                            {
                                trade.order1b.workingAge = DateTime.Now.Subtract(trade.order1b.TransactTime).TotalMilliseconds;
                                //trade.p1b = (long)algo.tasEngine.firstLeg.bestBid.Price + 1;
                                trade.p2s = (long)algo.tasEngine.secondLeg.bestBid.Price;
                                trade.p3s = (long)algo.tasEngine.spread.bestBid.Price;
                                trade.p1b = trade.p2s +trade.p3s - trade.ticks;
                                trade.p1s = trade.p1b + 3;
                                        
                                if ((trade.order1b.workingAge > 500) && trade.order1b.filledQuantity < 1)
                                {
                                    if (trade.p1b != trade.order1b.Price)
                                    {
                                        trade.order1b.Price = trade.p1b;
                                        algo.omsEngine.tradingManager.ModifyOrder(trade.order1b);
                                    }    
                                }

                                if (trade.order1b.Status == Order.OrderStatus.Fill)
                                {
                                    trade.status = 3;
                                    trade.initiateTime = DateTime.Now;
                                    System.Diagnostics.Trace.WriteLine("MBX Update: Initiated" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());

                                }
                            }
                                // sell - check logic again
                            else if (trade.initiateSide == 2)
                            {
                                if ((trade.order1s.Status == Order.OrderStatus.PendingNew) && (algo.tasEngine.firstLeg.bestBid.Price - algo.tasEngine.secondLeg.bestAsk.Price - algo.tasEngine.spread.bestAsk.Price - trade.ticks < 0))
                                {
                                    trade.order1s.Price = (long)algo.tasEngine.firstLeg.bestAsk.Price - 1;
                                    trade.order2b.Price = (long)algo.tasEngine.secondLeg.bestBid.Price + 1;
                                    trade.order3b.Price = (long)algo.tasEngine.spread.bestBid.Price + 1;
                                    algo.omsEngine.tradingManager.ModifyOrder(trade.order1s);
                                }
                                else if (algo.tasEngine.firstLeg.bestBid.Price - algo.tasEngine.secondLeg.bestAsk.Price - algo.tasEngine.spread.bestAsk.Price + trade.ticks >= 0)
                                {
                                    trade.order1s.Price = (long)algo.tasEngine.firstLeg.bestAsk.Price - 1 + trade.ticks;
                                    trade.order2b.Price = (long)algo.tasEngine.secondLeg.bestBid.Price + 1;
                                    trade.order3b.Price = (long)algo.tasEngine.spread.bestBid.Price + 1;
                                    algo.omsEngine.tradingManager.ModifyOrder(trade.order1s);
                                }

                            }                          
                        
                            #endregion
                        }
                        if (trade.status == 3)
                        {
                            #region
                            initiatedAge = DateTime.Now.Subtract(trade.initiateTime);
                            #region
                            if (trade.initiateSide == 1)
                            {
                                if (trade.order2s.Status == Order.OrderStatus.PendingNew)
                                {
                                    trade.order2s.Price = trade.p2s;

                                    if (trade.order2s.quantity != trade.order1b.filledQuantity)
                                        trade.order2s.quantity = trade.order1b.filledQuantity;

                                    algo.omsEngine.tradingManager.SendNewOrder(trade.order2s);
                                }

                                if (trade.order3s.Status == Order.OrderStatus.PendingNew)
                                {
                                    trade.order3s.Price = trade.p3s;

                                    if (trade.order3s.quantity != trade.order1b.filledQuantity)
                                        trade.order3s.quantity = trade.order1b.filledQuantity;

                                    algo.omsEngine.tradingManager.SendNewOrder(trade.order3s);
                                }

                                if (trade.order2s.Status == Order.OrderStatus.Fill && trade.order3s.Status == Order.OrderStatus.Fill && trade.order1b.Status == Order.OrderStatus.Fill)
                                {
                                    trade.status = 5;
                                    System.Diagnostics.Trace.WriteLine("MBX Update: Completed" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());
                                    algo.tradeCreated = false;
                                }


                                /*
                                if ((trade.fPos <= trade.initiateQuantity) && (trade.sPos < trade.fPos)) // partial fill
                                {
                                    if (trade.sPos > 0 && trade.sprPos < trade.sPos)
                                    {
                                        trade.order3s.Quantity = trade.sPos - trade.sprPos;
                                        trade.order3s.Price = (long)trade.fAvgPrice - trade.ticks - trade.sAvgPrice;
                                        if (trade.order3s.Status == Order.OrderStatus.New)
                                            algo.omsEngine.tradingManager.SendNewOrder(trade.order3s);
                                        else
                                            algo.omsEngine.tradingManager.ModifyOrder(trade.order3s);
                                    }
                                    
                                    // write code to improve logic - i.e. by working second leg and improving trade.ticks
                                    trade.order2s.Price = trade.fAvgPrice - trade.ticks - (long)algo.tasEngine.spread.bestBid.Price;
                                    trade.order3s.Price = trade.fAvgPrice - trade.ticks - trade.order2s.Price;
                                    trade.order2s.Quantity = trade.fPos - trade.sPos;

                                    trade.order1b.Price = (long)algo.tasEngine.firstLeg.bestBid.Price + 1; //work the balance order as per the autospreader
                                    trade.order1b.quantity = trade.order1b.originalQuantity - trade.order1b.filledQuantity; // check if required
                                    algo.omsEngine.tradingManager.ModifyOrder(trade.order1b);

                                    if (trade.order2s.Status == Order.OrderStatus.New)
                                        algo.omsEngine.tradingManager.SendNewOrder(trade.order2s);
                                    else
                                        algo.omsEngine.tradingManager.ModifyOrder(trade.order2s);
                                }*/
                            }
                            else if (trade.initiateSide == 2)
                            {
                                if ((trade.fPos <= trade.initiateQuantity) && (trade.sPos < trade.fPos)) // partial fill
                                {
                                    if (trade.sPos > 0 && trade.sprPos < trade.sPos)
                                    {
                                        trade.order3b.Quantity = trade.sPos - trade.sprPos;
                                        trade.order3b.Price = trade.sAvgPrice - trade.fAvgPrice + trade.ticks;

                                        trade.order1s.Price = (long)algo.tasEngine.firstLeg.bestAsk.Price - 1;//work the balance order as per the autospreader
                                        trade.order1s.quantity = trade.order1s.originalQuantity - trade.order1s.filledQuantity; // check if required                                    
                                        algo.omsEngine.tradingManager.ModifyOrder(trade.order1s);

                                        if (trade.order3b.Status == Order.OrderStatus.New)
                                            algo.omsEngine.tradingManager.SendNewOrder(trade.order3b);
                                        else
                                            algo.omsEngine.tradingManager.ModifyOrder(trade.order3b);
                                            
                                    }
                                    // write code to improve logic - i.e. by working second leg and improving trade.ticks
                                    trade.order2b.Price = trade.fAvgPrice - trade.ticks + (long)algo.tasEngine.spread.bestAsk.Price;
                                    trade.order3b.Price = trade.sAvgPrice - trade.fAvgPrice + trade.ticks;
                                    trade.order2b.Quantity = trade.fPos - trade.sPos;

                                    if (trade.order2b.Status == Order.OrderStatus.New)
                                        algo.omsEngine.tradingManager.SendNewOrder(trade.order2b);
                                    else
                                        algo.omsEngine.tradingManager.ModifyOrder(trade.order2b);
                                }
                            }

                            #endregion
                            // first leg initiated. place market order for second and third leg
                            

                            // handle partial fills


                            // improve this logic
                            #region
                            /*
                            if (trade.fPos == trade.sPos && trade.fPos == trade.sprPos && trade.fPos == trade.initiateQuantity)
                            {
                                trade.status = 5;
                                System.Diagnostics.Trace.WriteLine("MBX Update: Completed" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());
                                algo.tradeCreated = false;
                            }
                            else
                            {
                                // read market data. if slippage happens set status to 4
                                if (trade.initiateSide == 1)
                                {
                                    trade.mtm1 = trade.order1b.lastFillPrice - algo.tasEngine.firstLeg.bestBid.Price;
                                    if ((trade.mtm1 > trade.ticks) && ((algo.tasEngine.secondLeg.bestBid.Price + algo.tasEngine.spread.bestBid.Price - trade.fAvgPrice) > trade.ticks) &&(trade.order2s.filledQuantity==0))
                                    {
                                        trade.status = 4;
                                        System.Diagnostics.Trace.WriteLine("MBX Update: Slippage" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());

                                    }
                                }
                                else if (trade.initiateSide == 2)
                                {
                                    trade.mtm1 = algo.tasEngine.firstLeg.bestAsk.Price - trade.order1s.lastFillPrice;
                                    if ((trade.mtm1 > trade.ticks) && ((algo.tasEngine.secondLeg.bestAsk.Price + algo.tasEngine.spread.bestAsk.Price - trade.fAvgPrice) > trade.ticks) && (trade.order2b.filledQuantity == 0))
                                    {
                                        trade.status = 4;
                                        System.Diagnostics.Trace.WriteLine("MBX Update: Slippage" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());

                                    }
                                }
                            }*/
                            #endregion
                            #endregion
                        }
                        if (trade.status == 4)
                        {
                            #region
                            initiatedAge = DateTime.Now.Subtract(trade.initiateTime);
                            // if slippage happens, convert trade to type 1, 2 or 4 and handle.
                            // first leg initiated. slippage occured on second leg
                            // consider changing type from type 5 to type 1 or 4.

                            if (initiatedAge.TotalMilliseconds > 30000)
                                if (trade.initiateSide == 1)
                                {
                                    if(trade.order2s.filledQuantity == 0 && trade.order3s.filledQuantity == 0)
                                    {
                                        algo.omsEngine.tradingManager.CancelOrder(trade.order2s);
                                        algo.omsEngine.tradingManager.CancelOrder(trade.order3s);

                                        while(trade.order2s.Status != Order.OrderStatus.Canceled || trade.order3s.Status != Order.OrderStatus.Canceled)
                                        {
                                            if(trade.order2s.filledQuantity >0 || trade.order3s.filledQuantity>0)
                                            {
                                                trade.status = 3;
                                                System.Diagnostics.Trace.WriteLine("MBX Update: Initiated" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());
                                                break;
                                            }
                                        }
                                        if (trade.order2s.Status == Order.OrderStatus.Canceled && trade.order3s.Status == Order.OrderStatus.Canceled)
                                        {
                                            trade.tradeType = 1;
                                            System.Diagnostics.Trace.WriteLine("MBX Update: Reset" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());

                                        }
                                        
                                    }

                                }
                               else if (trade.initiateSide == 2)
                                {
                                    if (trade.order2b.filledQuantity == 0 && trade.order3b.filledQuantity == 0)
                                    {
                                        algo.omsEngine.tradingManager.CancelOrder(trade.order2b);
                                        algo.omsEngine.tradingManager.CancelOrder(trade.order3b);

                                        while (trade.order2b.Status != Order.OrderStatus.Canceled || trade.order3b.Status != Order.OrderStatus.Canceled)
                                        {
                                            if (trade.order2b.filledQuantity > 0 || trade.order3b.filledQuantity > 0)
                                            {
                                                trade.status = 3;
                                                System.Diagnostics.Trace.WriteLine("MBX Update: Initiated" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());
                                                break;
                                            }
                                        }
                                        if (trade.order2b.Status == Order.OrderStatus.Canceled && trade.order3b.Status == Order.OrderStatus.Canceled)
                                        {
                                            trade.tradeType = 1;
                                            System.Diagnostics.Trace.WriteLine("MBX Update: Reset" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());
                                            
                                        }

                                    }
                                }


                            // code to book loss
#endregion 
                        }
                        if (trade.status == 5)
                        {
                            // trade closed. exit the loops and the thread
                            // remove the Trade and its corresponding orders from the current list and add them to closed list
                            algo.fsSprTradeBook.Remove(trade);
                            algo.tradeBookClosed.Add(trade);
                            break;
                        }
                        if (trade.status == 7)
                        {
                            // trade cancelled. exit the loops and the thread
                            // remove the Trade and its corresponding orders from the current list and add them to closed list
                            args.algo.fsHTradeBook.Remove(trade);
                            args.algo.tradeBookCancelled.Add(trade);
                            break;
                        }
                    }
                    #endregion

                    else if (trade.tradeType == 1)  
                    {
                        #region FAST MARKET MAKING
                        /*
                        if (trade.order1b.filledQuantity != trade.order1s.filledQuantity)
                            trade.status = 3;
                        if (trade.order1bb.filledQuantity != trade.order1ss.filledQuantity)
                            trade.status = 4;
                          */

                        // for trade type 2, do the following
                        if (trade.status == 1)
                        {
                            #region NEWLY CREATED
                            // trade is newly generated. create orders here. place orders. if orders are accepted change status to 2
                            if (trade.initiateSide == 1) // buy
                            {
                                #region BUY
                                if (trade.order1b.filledQuantity > 0)
                                {
                                    trade.order1b.Status = Order.OrderStatus.Fill;
                                    trade.status = 3;
                                    continue;
                                }

                                if (trade.order1b.Status == Order.OrderStatus.PendingNew || trade.reset)
                                {

                                    dtemp1 = algo.GetClosestM50(algo.tasEngine.firstLeg.lastTradedPrice);
                                    dtemp2 = dtemp1 - algo.tasEngine.firstLeg.lastTradedPrice;

                                    betemp1 = algo.tasEngine.firstLeg.getBOLL(30);
                                    ohlctemp1 = algo.tasEngine.firstLeg.getOHLC(10);

                                    if (dtemp2 < 0 && dtemp2 > -3) // if closest50 is less than 10 ticks below ltp
                                    {
                                        trade.p1b = dtemp1 + 1;
                                    }
                                    else
                                    {
                                        if (betemp1.MiddleLevel > algo.tasEngine.firstLeg.lastTradedPrice) // if ltp is in lower band
                                        {
                                            if ((algo.tasEngine.firstLeg.lastTradedPrice - betemp1.LowerLevel) < 3)
                                                trade.p1b = betemp1.LowerLevel + 1;
                                            else
                                                trade.p1b = algo.tasEngine.firstLeg.lastTradedPrice - 3;
                                        }
                                        else // if ltp is in upper band
                                        {
                                            if ((algo.tasEngine.firstLeg.lastTradedPrice - betemp1.MiddleLevel) < 3)
                                                trade.p1b = betemp1.MiddleLevel + 1;
                                            else
                                                trade.p1b = algo.tasEngine.firstLeg.lastTradedPrice - 3;
                                        }
                                    }

                                    if (trade.reset == false)
                                    {
                                        trade.order1b.Price = trade.p1b;
                                        algo.omsEngine.tradingManager.SendNewOrder(trade.order1b);
                                    }
                                    else
                                    {
                                        trade.order1b.Price = trade.p1b;
                                        algo.omsEngine.tradingManager.ModifyOrder(trade.order1b);
                                        while (trade.order1b.Status != Order.OrderStatus.Replace)
                                        {
                                            Thread.Sleep(0);
                                            if (trade.order1b.filledQuantity == 1)
                                            {
                                                trade.order1b.Status = Order.OrderStatus.Fill;
                                                trade.status = 3;
                                                break;
                                            }
                                        }
                                        trade.reset = false;
                                    }
                                }
                                else
                                {
                                    trade.status = 2;
                                    System.Diagnostics.Trace.WriteLine("MBX Update: Initiating" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());
                                }
                                #endregion
                            }
                            else //sell
                            {
                                #region SELL

                                if (trade.order1s.filledQuantity > 0)
                                {
                                    trade.order1s.Status = Order.OrderStatus.Fill;
                                    trade.status = 3;
                                    continue;
                                }

                                if (trade.order1s.Status == Order.OrderStatus.PendingNew || trade.reset)
                                {
                                    dtemp1 = algo.GetClosestM50(algo.tasEngine.firstLeg.lastTradedPrice);
                                    dtemp2 = algo.tasEngine.firstLeg.lastTradedPrice - dtemp1;

                                    betemp1 = algo.tasEngine.firstLeg.getBOLL(60);
                                    ohlctemp1 = algo.tasEngine.firstLeg.getOHLC(60);

                                    if (betemp1.UpperLevel > 0)
                                    {
                                        Console.WriteLine(betemp1.UpperLevel);
                                    }

                                    if (dtemp2 < 0 && dtemp2 > -10) // if closest50 is less than 10 ticks above ltp
                                    {
                                        trade.p1s = dtemp1 - 2;
                                    }
                                    else
                                    {
                                        if (betemp1.MiddleLevel > algo.tasEngine.firstLeg.lastTradedPrice) // if ltp is in lower band
                                        {
                                            if ((betemp1.MiddleLevel - algo.tasEngine.firstLeg.lastTradedPrice) < 10)
                                                trade.p1s = betemp1.MiddleLevel - 2;
                                            else
                                                trade.p1s = algo.tasEngine.firstLeg.lastTradedPrice + 10;
                                        }
                                        else // if ltp is in upper band
                                        {
                                            if ((betemp1.UpperLevel - algo.tasEngine.firstLeg.lastTradedPrice) < 10)
                                                trade.p1s = betemp1.UpperLevel - 2;
                                            else
                                                trade.p1s = algo.tasEngine.firstLeg.lastTradedPrice + 10;
                                        }
                                    }

                                    if (trade.reset == false)
                                    {
                                        trade.order1s.Price = trade.p1s;
                                        algo.omsEngine.tradingManager.SendNewOrder(trade.order1s);
                                    }
                                    else
                                    {
                                        trade.order1s.Price = trade.p1s;
                                        algo.omsEngine.tradingManager.ModifyOrder(trade.order1s);

                                        while (trade.order1s.Status != Order.OrderStatus.Replace)
                                        {
                                            Thread.Sleep(0);
                                            if (trade.order1s.filledQuantity == 1)
                                            {
                                                trade.order1s.Status = Order.OrderStatus.Fill;
                                                trade.status = 3;
                                                break;
                                            }
                                        }

                                        trade.reset = false;
                                    }

                                }
                                else
                                {
                                    trade.status = 2;
                                    System.Diagnostics.Trace.WriteLine("MBX Update: Initiating" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());

                                }
                                #endregion
                            }
                            #endregion
                        }
                        if (trade.status == 2)
                        {
                            #region FIRST ORDER PLACED
                            // orders placed and working.
                            // check if all orders are still working. 
                            // if yes, modify / monitor. if no, set initiate leg, unhedged quantities and change status to 3
                            createdAge = DateTime.Now.Subtract(trade.createTime);
                            // Trade initiated 
                            if (trade.initiateSide == 1)
                            {
                                #region BUY

                                if (trade.order1b.filledQuantity > 0)
                                {
                                    trade.order1b.Status = Order.OrderStatus.Fill;
                                    trade.status = 3;
                                    continue;
                                }

                                trade.order1b.workingAge = DateTime.Now.Subtract(trade.order1b.TransactTime).TotalMilliseconds;

                                if (trade.order1b.workingAge > 1000 && (trade.order1b.Status == Order.OrderStatus.New || trade.order1b.Status == Order.OrderStatus.Replace))
                                {
                                    if ((algo.tasEngine.firstLeg.lastTradedPrice - trade.order1b.Price) > 3)
                                    {
                                        trade.reset = true;
                                        trade.status = 1;
                                        continue;
                                    }
                                }

                                if (trade.order1b.Status == Order.OrderStatus.Fill)
                                {
                                    trade.status = 3;
                                    trade.initiateTime = DateTime.Now;
                                    System.Diagnostics.Trace.WriteLine("MBX Update: Initiated" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());

                                }
                                #endregion
                            }
                            else if (trade.initiateSide == 2)
                            {
                                #region SELL
                                if (trade.order1s.filledQuantity > 0)
                                {
                                    trade.order1s.Status = Order.OrderStatus.Fill;
                                    trade.status = 3;
                                    continue;
                                }

                                trade.order1s.workingAge = DateTime.Now.Subtract(trade.order1s.TransactTime).TotalMilliseconds;

                                if (trade.order1s.workingAge > 5000 && trade.order1s.Status == Order.OrderStatus.New)
                                {
                                    if ((trade.order1b.Price - algo.tasEngine.firstLeg.lastTradedPrice) > 20)
                                    {
                                        trade.reset = true;
                                        trade.status = 1;
                                        continue;
                                    }
                                }

                                if ((trade.order1s.Status == Order.OrderStatus.PartialFill || trade.order1s.Status == Order.OrderStatus.Fill))
                                {
                                    trade.status = 3;
                                    trade.initiateTime = DateTime.Now;
                                    System.Diagnostics.Trace.WriteLine("MBX Update: Initiated" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());
                                }
                                #endregion
                            }
                            #endregion
                        }
                        if (trade.status == 3)
                        {
                            #region PLACE SECOND ORDER

                            Thread.Sleep(0);

                            // first leg initiated. place exit order 
                            // read market data. if slippage happens set status to 4                            

                            if (trade.initiateSide == 1)
                            {
                                #region BUY

                                if (trade.order1s.filledQuantity > 0 && trade.order1s.Status != Order.OrderStatus.Fill)
                                {
                                    trade.order1s.Status = Order.OrderStatus.Fill;
                                }

                                if (trade.order1bb.Status != Order.OrderStatus.Canceled && trade.order1bb.Status != Order.OrderStatus.PendingNew && trade.order1bb.filledQuantity == 0)
                                {
                                    algo.omsEngine.tradingManager.CancelOrder(trade.order1bb);
                                    while (trade.order1bb.Status != Order.OrderStatus.Canceled)
                                    {
                                        Thread.Sleep(0);
                                        if (trade.order1bb.filledQuantity == 1 && trade.order1bb.filledQuantity == trade.order1bb.quantity)
                                        {
                                            trade.order1bb.Status = Order.OrderStatus.Fill;
                                            trade.status = 4;
                                            break;
                                        }
                                        else if (trade.order1bb.filledQuantity == 1 && trade.order1bb.filledQuantity < trade.order1bb.quantity)
                                        {
                                            trade.order1bb.Status = Order.OrderStatus.PartialFill;
                                            trade.status = 4;
                                            break;
                                        }

                                    }
                                }

                                if (trade.order1bb.Status == Order.OrderStatus.Fill || trade.order1bb.Status == Order.OrderStatus.PartialFill)
                                {
                                    if (trade.order1bb.filledQuantity != trade.order1ss.filledQuantity)
                                    {
                                        trade.status = 4;
                                        continue;
                                    }
                                }

                                if (trade.order1s.Status != Order.OrderStatus.New && trade.order1s.Status != Order.OrderStatus.Fill && trade.order1s.Status != Order.OrderStatus.Replace) // check if status should be new or pendingnew
                                {
                                    trade.p1s = trade.order1b.LastFillPrice + 2;
                                    trade.order1s.Price = trade.p1s;
                                    algo.omsEngine.tradingManager.SendNewOrder(trade.order1s);
                                }
                                else if (trade.order1s.Status == Order.OrderStatus.Fill)
                                {
                                    if ((trade.order1bb.Status == Order.OrderStatus.PendingNew && trade.order1ss.Status == Order.OrderStatus.PendingNew)
                                        || ((trade.order1bb.filledQuantity == trade.order1ss.filledQuantity)
                                        && ((trade.order1bb.Status == Order.OrderStatus.Fill && trade.order1ss.Status == Order.OrderStatus.Fill)
                                        || (trade.order1bb.Status == Order.OrderStatus.Canceled && trade.order1ss.Status == Order.OrderStatus.Canceled)
                                        || (trade.order1bb.Status == Order.OrderStatus.PartialFill && trade.order1ss.Status == Order.OrderStatus.PartialFill))))
                                    {
                                        trade.status = 5;
                                        System.Diagnostics.Trace.WriteLine("MBX Update: Completed" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());
                                        //continue;
                                    }
                                    else if (trade.order1bb.filledQuantity != trade.order1ss.filledQuantity)
                                    {
                                        trade.status = 4;
                                        continue;
                                    }

                                }
                                else if (trade.order1s.Status == Order.OrderStatus.New || trade.order1s.Status == Order.OrderStatus.PartialFill)
                                {
                                    if ((algo.tasEngine.firstLeg.lastTradedPrice - trade.order1b.lastFillPrice) <= -3)
                                    {
                                        trade.status = 4;
                                        System.Diagnostics.Trace.WriteLine("MBX Update: Slippage" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());
                                    }
                                }

                                #endregion
                            }
                            else if (trade.initiateSide == 2)
                            {
                                #region SELL
                                if (trade.order1b.filledQuantity > 0)
                                {
                                    trade.order1b.Status = Order.OrderStatus.Fill;
                                }

                                if (trade.order1ss.Status != Order.OrderStatus.Canceled && trade.order1ss.Status != Order.OrderStatus.PendingNew)
                                {
                                    algo.omsEngine.tradingManager.CancelOrder(trade.order1ss);
                                    while (trade.order1ss.Status != Order.OrderStatus.Canceled)
                                    {
                                        Thread.Sleep(0);
                                        if (trade.order1ss.filledQuantity == 1)
                                        {
                                            trade.order1ss.Status = Order.OrderStatus.Fill;
                                            trade.status = 4;
                                            break;
                                        }
                                    }
                                }
                                if (trade.order1ss.Status == Order.OrderStatus.Fill || trade.order1ss.Status == Order.OrderStatus.PartialFill)
                                {
                                    trade.status = 4;
                                    continue;
                                }

                                if (trade.order1b.Status != Order.OrderStatus.New && trade.order1b.Status != Order.OrderStatus.Fill)
                                {
                                    trade.p1b = trade.order1s.lastFillPrice - 3;
                                    trade.order1b.Price = trade.p1b;
                                    algo.omsEngine.tradingManager.SendNewOrder(trade.order1b);
                                }
                                else if (trade.order1b.Status == Order.OrderStatus.Fill)
                                {
                                    trade.status = 5;
                                    System.Diagnostics.Trace.WriteLine("MBX Update: Completed" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());
                                }
                                else if (trade.order1b.Status == Order.OrderStatus.New || trade.order1b.Status == Order.OrderStatus.PartialFill)
                                {
                                    if ((algo.tasEngine.firstLeg.lastTradedPrice - trade.order1s.lastFillPrice) > 5)
                                    {
                                        trade.status = 4;
                                        System.Diagnostics.Trace.WriteLine("MBX Update: Slippage" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());
                                    }
                                }
                                #endregion
                            }
                            #endregion
                        }
                        if (trade.status == 4) // Slippage happened - double up and exit
                        {
                            #region SLIPPAGE

                            Thread.Sleep(0);
                            initiatedAge = DateTime.Now.Subtract(trade.initiateTime);

                            if (trade.initiateSide == 1)
                            {
                                #region BUY
                                if (trade.order1s.Status == Order.OrderStatus.Fill
                                    && (trade.order1bb.filledQuantity == 0)
                                    && (trade.order1ss.filledQuantity == 0))
                                {
                                    if (trade.order1bb.Status != Order.OrderStatus.PendingNew)
                                    {
                                        algo.omsEngine.tradingManager.CancelOrder(trade.order1bb);
                                        while (trade.order1bb.Status != Order.OrderStatus.Canceled || trade.order1bb.filledQuantity != 0)
                                        {
                                            Thread.Sleep(0);
                                            if (trade.order1bb.filledQuantity > 0)
                                            {
                                                trade.order1bb.Status = Order.OrderStatus.Fill;
                                                break;
                                            }
                                        }
                                    }

                                    if (trade.order1ss.Status != Order.OrderStatus.PendingNew)
                                    {
                                        algo.omsEngine.tradingManager.CancelOrder(trade.order1ss);
                                        while (trade.order1ss.Status != Order.OrderStatus.Canceled)
                                        {
                                            Thread.Sleep(0);
                                            if (trade.order1ss.filledQuantity == 1)
                                            {
                                                trade.order1ss.Status = Order.OrderStatus.Fill;
                                                break;
                                            }
                                        }
                                    }

                                    if ((trade.order1bb.Status == Order.OrderStatus.PendingNew || trade.order1bb.Status == Order.OrderStatus.Canceled)
                                        && (trade.order1ss.Status == Order.OrderStatus.PendingNew || trade.order1ss.Status == Order.OrderStatus.Canceled)
                                        && trade.order1s.Status == Order.OrderStatus.Fill)
                                    {
                                        trade.status = 5;
                                        System.Diagnostics.Trace.WriteLine("MBX Update: Completed" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());
                                        
                                    }

                                }

                                if (trade.order1bb.Status == Order.OrderStatus.Canceled || (trade.order1bb.Status == Order.OrderStatus.Fill && trade.order1ss.Status == Order.OrderStatus.Fill))
                                    trade.order1bb = algo.CreateOrder(trade.tradeID, trade.legOne, 1, Order.OrderType.Limit);
                                if (trade.order1ss.Status == Order.OrderStatus.Canceled || (trade.order1bb.Status == Order.OrderStatus.Fill && trade.order1ss.Status == Order.OrderStatus.Fill) || (trade.order1bb.Status == Order.OrderStatus.PendingNew && trade.order1ss.Status == Order.OrderStatus.Fill))
                                    trade.order1ss = algo.CreateOrder(trade.tradeID, 1, trade.legOne, Order.OrderType.Limit);


                                if (trade.order1bb.Status != Order.OrderStatus.New && trade.order1bb.filledQuantity < 1)
                                {
                                    lock (algo.tasEngine.firstLeg.rwLock)
                                    {
                                        // System.Diagnostics.Trace.WriteLine("MBX Update: DBG READING : " + algo.tasEngine.firstLeg.ID + " : " + algo.tasEngine.firstLeg.Desc + " : " + algo.tasEngine.firstLeg.lastTradedPrice.ToString());

                                        if ((algo.tasEngine.firstLeg.lastTradedPrice - trade.order1b.lastFillPrice) <= -3)
                                        {
                                            trade.order1bb.quantity = 2;
                                            trade.p1bb = trade.order1b.lastFillPrice - 3;
                                        }
                                        else if ((algo.tasEngine.firstLeg.lastTradedPrice - trade.order1b.lastFillPrice) <= -1)
                                        {
                                            trade.p1bb = trade.order1b.lastFillPrice - 1;
                                        }
                                        else
                                        {
                                            trade.status = 3;
                                            System.Diagnostics.Trace.WriteLine("MBX Update: Slippage Retraced" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());
                                            continue;
                                        }

                                        trade.order1bb.Price = trade.p1bb;
                                        algo.omsEngine.tradingManager.SendNewOrder(trade.order1bb);
                                    }

                                }
                                else if (trade.order1bb.Status == Order.OrderStatus.PartialFill)
                                {
                                    trade.order1ss.quantity = trade.order1bb.filledQuantity - trade.order1ss.filledQuantity;
                                    trade.p1ss = trade.order1bb.lastFillPrice + 3;
                                    if (trade.order1s.Status != Order.OrderStatus.Replace)
                                        trade.p1s = trade.p1ss + 1;

                                    if (trade.order1s.Price != trade.p1s)
                                    {
                                        algo.omsEngine.tradingManager.ModifyOrder(trade.order1s);

                                        while (trade.order1s.Status != Order.OrderStatus.Replace)
                                        {
                                            Thread.Sleep(0);
                                            if (trade.order1s.filledQuantity == 1)
                                            {
                                                trade.order1s.Status = Order.OrderStatus.Fill;
                                                break;
                                            }
                                        }
                                    }

                                    if (trade.order1ss.Status == Order.OrderStatus.PendingNew)
                                    {
                                        trade.order1ss.Price = trade.p1ss;
                                        algo.omsEngine.tradingManager.SendNewOrder(trade.order1ss);
                                    }

                                }
                                else if (trade.order1bb.Status == Order.OrderStatus.Fill && trade.order1ss.filledQuantity != trade.order1bb.filledQuantity)
                                {
                                    if (trade.order1ss.Status == Order.OrderStatus.PendingNew)
                                    {
                                        trade.order1ss.quantity = trade.order1bb.filledQuantity - trade.order1ss.filledQuantity;
                                        trade.p1ss = trade.order1bb.lastFillPrice + 3;
                                        if (trade.order1s.Status != Order.OrderStatus.Replace)
                                            trade.p1s = trade.order1ss.Price+1;

                                        trade.order1ss.Price = trade.p1ss;
                                        algo.omsEngine.tradingManager.SendNewOrder(trade.order1ss);
                                        if (trade.order1s.Price != trade.p1s)
                                        {
                                            algo.omsEngine.tradingManager.ModifyOrder(trade.order1s);

                                            while (trade.order1s.Status != Order.OrderStatus.Replace)
                                            {
                                                Thread.Sleep(0);
                                                if (trade.order1s.filledQuantity == 1)
                                                {
                                                    trade.order1s.Status = Order.OrderStatus.Fill;
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                    else if (trade.order1ss.Status == Order.OrderStatus.New || trade.order1ss.quantity != trade.order1bb.filledQuantity || trade.order1ss.Price != (trade.order1bb.lastFillPrice + 3))
                                    {
                                        trade.order1ss.quantity = trade.order1bb.filledQuantity - trade.order1ss.filledQuantity;
                                        trade.p1ss = trade.order1bb.lastFillPrice + 3;

                                        if (trade.order1ss.Price != trade.p1ss)
                                        {
                                            algo.omsEngine.tradingManager.ModifyOrder(trade.order1ss);
                                            while (trade.order1ss.Status != Order.OrderStatus.Replace)
                                            {
                                                Thread.Sleep(0);
                                                if (trade.order1ss.filledQuantity == 1)
                                                {
                                                    trade.order1ss.Status = Order.OrderStatus.Fill;
                                                    break;
                                                }
                                            }
                                        }
                                        if (trade.order1s.Price != trade.order1ss.Price && trade.order1s.Status != Order.OrderStatus.Replace)
                                        {
                                            trade.order1s.Price = trade.order1ss.Price;
                                            algo.omsEngine.tradingManager.ModifyOrder(trade.order1s);

                                            while (trade.order1s.Status != Order.OrderStatus.Replace)
                                            {
                                                Thread.Sleep(0);
                                                if (trade.order1s.filledQuantity == 1)
                                                {
                                                    trade.order1s.Status = Order.OrderStatus.Fill;
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                }

                                if (trade.order1ss.filledQuantity == trade.order1bb.filledQuantity && trade.order1s.filledQuantity == 0 && trade.order1ss.Status == Order.OrderStatus.Fill)
                                {
                                    if ((algo.tasEngine.firstLeg.lastTradedPrice - trade.order1b.lastFillPrice) >= -1)
                                    {
                                        trade.status = 3;
                                        System.Diagnostics.Trace.WriteLine("MBX Update: Slippage Retraced" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());
                                        continue;
                                    }

                                    // write code to convert it to status 3 based on ohlc and boll levels - trade reset
                                    //System.Diagnostics.Trace.WriteLine("MBX Update: Initiated" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());

                                }
                                if (trade.order1ss.filledQuantity == trade.order1bb.filledQuantity && trade.order1s.Status == Order.OrderStatus.Fill && trade.order1ss.Status == Order.OrderStatus.Fill)
                                {
                                    trade.status = 5;
                                    System.Diagnostics.Trace.WriteLine("MBX Update: Completed" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());
                                    //continue;
                                }

                                if (trade.order1bb.Status == Order.OrderStatus.New)
                                {
                                    if ((algo.tasEngine.firstLeg.lastTradedPrice - trade.order1b.lastFillPrice) > 1 || trade.order1s.Status == Order.OrderStatus.Fill)
                                    {
                                        // check the next line
                                        if (trade.order1bb.Status != Order.OrderStatus.Canceled && trade.order1bb.Status != Order.OrderStatus.PendingCancel)
                                        {
                                            algo.omsEngine.tradingManager.CancelOrder(trade.order1bb);
                                            while (trade.order1bb.Status != Order.OrderStatus.Canceled)
                                            {
                                                Thread.Sleep(0);
                                                if (trade.order1bb.filledQuantity == 1)
                                                {
                                                    trade.order1bb.Status = Order.OrderStatus.Fill;
                                                    trade.status = 4;
                                                    break;
                                                }
                                            }
                                        }

                                        if (trade.order1bb.Status == Order.OrderStatus.Canceled)
                                        {
                                            trade.status = 3;
                                            continue;
                                        }
                                    }
                                }
                                #endregion
                            }
                            else if (trade.initiateSide == 2)
                            {
                                #region SELL
                                if (trade.order1b.Status == Order.OrderStatus.Fill
                                    && (trade.order1ss.filledQuantity == 0)
                                    && (trade.order1bb.filledQuantity == 0))
                                {
                                    if (trade.order1ss.Status != Order.OrderStatus.PendingNew)
                                        algo.omsEngine.tradingManager.CancelOrder(trade.order1ss);
                                    {
                                        while (trade.order1ss.Status != Order.OrderStatus.Canceled)
                                        {
                                            Thread.Sleep(0);
                                            if (trade.order1ss.filledQuantity == 1)
                                            {
                                                trade.order1ss.Status = Order.OrderStatus.Fill;
                                                trade.status = 4;
                                                break;
                                            }
                                        }
                                    }

                                    if (trade.order1bb.Status != Order.OrderStatus.PendingNew)
                                    {
                                        algo.omsEngine.tradingManager.CancelOrder(trade.order1bb);
                                        while (trade.order1bb.Status != Order.OrderStatus.Canceled)
                                        {
                                            Thread.Sleep(0);
                                            if (trade.order1bb.filledQuantity == 1)
                                            {
                                                trade.order1bb.Status = Order.OrderStatus.Fill;
                                                trade.status = 4;
                                                break;
                                            }
                                        }
                                    }

                                    while ((trade.order1ss.Status != Order.OrderStatus.PendingNew && trade.order1ss.Status != Order.OrderStatus.Canceled)
                                        || (trade.order1bb.Status != Order.OrderStatus.PendingNew && trade.order1bb.Status != Order.OrderStatus.Canceled))
                                    {
                                        Thread.Sleep(0);
                                        if (trade.order1ss.filledQuantity > 0 || trade.order1bb.filledQuantity > 0)
                                            break;
                                    }

                                    if ((trade.order1ss.Status == Order.OrderStatus.PendingNew || trade.order1ss.Status == Order.OrderStatus.Canceled)
                                        && (trade.order1bb.Status == Order.OrderStatus.PendingNew || trade.order1bb.Status == Order.OrderStatus.Canceled))
                                    {
                                        trade.status = 5;
                                        System.Diagnostics.Trace.WriteLine("MBX Update: Completed" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());
                                        //continue;
                                    }

                                }

                                if (trade.order1ss.Status == Order.OrderStatus.Canceled)
                                    trade.order1ss = algo.CreateOrder(trade.tradeID, trade.legOne, 1, Order.OrderType.Limit);
                                if (trade.order1bb.Status == Order.OrderStatus.Canceled)
                                    trade.order1bb = algo.CreateOrder(trade.tradeID, 1, trade.legOne, Order.OrderType.Limit);


                                if (trade.order1ss.Status != Order.OrderStatus.New && trade.order1ss.filledQuantity < 1)
                                {
                                    if ((algo.tasEngine.firstLeg.lastTradedPrice - trade.order1s.lastFillPrice) >= 10)
                                    {
                                        trade.order1ss.quantity = 2;
                                        trade.p1ss = (long)algo.tasEngine.firstLeg.bestBid.Price;
                                    }
                                    else if ((algo.tasEngine.firstLeg.lastTradedPrice - trade.order1b.lastFillPrice) >= 5)
                                    {
                                        trade.p1ss = (long)algo.tasEngine.firstLeg.bestAsk.Price + 1;
                                    }


                                    if (trade.order1ss.Status != Order.OrderStatus.New && trade.order1ss.filledQuantity < 1) // check if it should be new or pending new
                                    {
                                        trade.order1ss.Price = trade.p1ss;
                                        algo.omsEngine.tradingManager.SendNewOrder(trade.order1ss);
                                    }
                                }
                                else if (trade.order1ss.Status == Order.OrderStatus.PartialFill)
                                {
                                    trade.order1bb.quantity = trade.order1ss.filledQuantity - trade.order1bb.filledQuantity;
                                    trade.p1bb = trade.order1ss.lastFillPrice - 5;
                                    trade.p1b = trade.p1bb - 1;

                                    if (trade.order1b.Price != trade.p1b)
                                    {
                                        algo.omsEngine.tradingManager.ModifyOrder(trade.order1b);

                                        while (trade.order1b.Status != Order.OrderStatus.Replace)
                                        {
                                            Thread.Sleep(0);
                                            if (trade.order1b.filledQuantity == 1)
                                            {
                                                trade.order1b.Status = Order.OrderStatus.Fill;
                                                break;
                                            }
                                        }
                                    }
                                    if (trade.order1bb.Status == Order.OrderStatus.PendingNew)
                                    {
                                        trade.order1bb.Price = trade.p1bb;
                                        algo.omsEngine.tradingManager.SendNewOrder(trade.order1bb);
                                    }

                                }
                                else if (trade.order1ss.Status == Order.OrderStatus.Fill && trade.order1bb.filledQuantity != trade.order1ss.filledQuantity)
                                {
                                    if (trade.order1bb.Status == Order.OrderStatus.PendingNew)
                                    {
                                        trade.order1bb.quantity = trade.order1ss.filledQuantity - trade.order1bb.filledQuantity;
                                        trade.p1bb = trade.order1ss.lastFillPrice - 5;
                                        trade.p1b = trade.order1bb.Price - 1;
                                        trade.order1bb.Price = trade.p1bb;
                                        algo.omsEngine.tradingManager.SendNewOrder(trade.order1bb);
                                        if (trade.order1b.Price != trade.p1b)
                                        {
                                            algo.omsEngine.tradingManager.ModifyOrder(trade.order1b);

                                            while (trade.order1b.Status != Order.OrderStatus.Replace)
                                            {
                                                Thread.Sleep(0);
                                                if (trade.order1b.filledQuantity == 1)
                                                {
                                                    trade.order1b.Status = Order.OrderStatus.Fill;
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                    else if (trade.order1bb.Status == Order.OrderStatus.New || trade.order1bb.quantity != trade.order1ss.filledQuantity || trade.order1bb.Price != (trade.order1ss.lastFillPrice - 5))
                                    {
                                        trade.order1bb.quantity = trade.order1ss.filledQuantity - trade.order1bb.filledQuantity;
                                        trade.p1bb = trade.order1ss.lastFillPrice - 5;

                                        if (trade.order1bb.Price != trade.p1bb)
                                        {
                                            algo.omsEngine.tradingManager.ModifyOrder(trade.order1bb);

                                            while (trade.order1bb.Status != Order.OrderStatus.Replace)
                                            {
                                                Thread.Sleep(0);
                                                if (trade.order1bb.filledQuantity == 1)
                                                {
                                                    trade.order1bb.Status = Order.OrderStatus.Fill;
                                                    break;
                                                }
                                            }
                                        }
                                        if (trade.order1b.Price != (trade.order1bb.Price - 1))
                                        {
                                            trade.order1b.Price = trade.order1bb.Price - 1;
                                            algo.omsEngine.tradingManager.ModifyOrder(trade.order1b);
                                            while (trade.order1b.Status != Order.OrderStatus.Replace)
                                            {
                                                Thread.Sleep(0);
                                                if (trade.order1b.filledQuantity == 1)
                                                {
                                                    trade.order1b.Status = Order.OrderStatus.Fill;
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                }

                                if (trade.order1bb.filledQuantity == trade.order1ss.filledQuantity && trade.order1b.filledQuantity == 0)
                                {
                                    // write code to convert it to status 3 based on ohlc and boll levels - trade reset
                                    //System.Diagnostics.Trace.WriteLine("MBX Update: Initiated" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());

                                }
                                if (trade.order1bb.filledQuantity == trade.order1ss.filledQuantity && trade.order1b.Status == Order.OrderStatus.Fill)
                                {
                                    // write code to convert it to status 3 based on ohlc and boll levels - trade reset
                                    trade.status = 5;
                                    System.Diagnostics.Trace.WriteLine("MBX Update: Completed" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());

                                }

                                if (trade.order1ss.Status == Order.OrderStatus.New)
                                {
                                    if ((algo.tasEngine.firstLeg.lastTradedPrice - trade.order1s.lastFillPrice) < 2 || trade.order1b.Status == Order.OrderStatus.Fill)
                                    {
                                        // check the next line
                                        if (trade.order1ss.Status != Order.OrderStatus.Canceled && trade.order1ss.Status != Order.OrderStatus.PendingCancel)
                                        {
                                            algo.omsEngine.tradingManager.CancelOrder(trade.order1ss);
                                            while (trade.order1ss.Status != Order.OrderStatus.Canceled)
                                            {
                                                Thread.Sleep(0);
                                                if (trade.order1ss.filledQuantity == 1)
                                                {
                                                    trade.order1ss.Status = Order.OrderStatus.Fill;
                                                    trade.status = 4;
                                                    break;
                                                }
                                            }
                                        }
                                        if (trade.order1ss.Status == Order.OrderStatus.Canceled)
                                            trade.status = 3;
                                    }
                                }

                                #endregion
                            }
                            #endregion
                        }
                        if (trade.status == 5)
                        {
                            #region TRADE CLOSURE
                            // trade closed. exit the loops and the thread
                            // remove the Trade and its corresponding orders from the current list and add them to closed list

                            if (trade.order1b.filledQuantity != trade.order1s.filledQuantity || trade.order1b.Status != Order.OrderStatus.Fill || trade.order1s.Status != Order.OrderStatus.Fill)
                                trade.status = 3;

                            if (trade.order1bb.filledQuantity != trade.order1ss.filledQuantity || (trade.order1bb.Status != Order.OrderStatus.Canceled && trade.order1bb.Status != Order.OrderStatus.PendingNew) || (trade.order1ss.Status != Order.OrderStatus.Canceled && trade.order1ss.Status != Order.OrderStatus.PendingNew))
                                trade.status = 4;

                            if (trade.status != 5)
                                continue;

                            args.algo.fMMTradeBook.Remove(trade);
                            args.algo.tradeBookClosed.Add(trade);
                            algo.tradeCreated = false;
                            break;
                            #endregion
                        }
                        if (trade.status == 7)
                        {
                            #region TRADE CANCELLED
                            // trade cancelled. exit the loops and the thread
                            // remove the Trade and its corresponding orders from the current list and add them to closed list
                            args.algo.fMMTradeBook.Remove(trade);
                            args.algo.tradeBookCancelled.Add(trade);
                            algo.tradeCreated = false;
                            break;
                            #endregion
                        }
                        #endregion
                    }
                    else if (trade.tradeType == 2)
                    {
                        #region SLOW MARKET MAKING
                        /*
                        if (trade.order1b.filledQuantity != trade.order1s.filledQuantity)
                            trade.status = 3;
                        if (trade.order1bb.filledQuantity != trade.order1ss.filledQuantity)
                            trade.status = 4;
                          */

                        // for trade type 2, do the following
                        if (trade.status == 1)
                        {
                            #region NEWLY CREATED
                            // trade is newly generated. create orders here. place orders. if orders are accepted change status to 2
                            if (trade.initiateSide == 1) // buy
                            {
                                #region BUY
                                if (trade.order1b.filledQuantity > 0)
                                {
                                    trade.order1b.Status = Order.OrderStatus.Fill;
                                    trade.status = 3;
                                    continue;
                                }
                               
                                if (trade.order1b.Status == Order.OrderStatus.PendingNew || trade.reset)
                                {
                                    
                                    lClosest50_1 = algo.GetClosestM50(algo.tasEngine.firstLeg.lastTradedPrice);
                                    dtemp2 = lClosest50_1 - algo.tasEngine.firstLeg.lastTradedPrice;
                                    if(dtemp2>0)
                                    {
                                        lClosest50_2 = lClosest50_1 - 50;
                                    }
                                    else
                                    {
                                        lClosest50_2 = lClosest50_1+50;
                                    }

                                    betemp1 = algo.tasEngine.firstLeg.getBOLL(60);
                                    ohlctemp1 = algo.tasEngine.firstLeg.getOHLC(60);

                                    if (dtemp2 < 0 && dtemp2 > -10) // if closest50 is less than 10 ticks below ltp
                                    {
                                        trade.p1b= dtemp1 + 2;
                                    }
                                    else
                                    {
                                        if (betemp1.MiddleLevel > algo.tasEngine.firstLeg.lastTradedPrice) // if ltp is in lower band
                                        {
                                            if ((algo.tasEngine.firstLeg.lastTradedPrice - betemp1.LowerLevel) < 10)
                                                trade.p1b= betemp1.LowerLevel + 2;
                                            else
                                                trade.p1b= algo.tasEngine.firstLeg.lastTradedPrice - 10;
                                        }
                                        else // if ltp is in upper band
                                        {
                                            if ((algo.tasEngine.firstLeg.lastTradedPrice - betemp1.MiddleLevel) < 10)
                                                trade.p1b= betemp1.MiddleLevel + 2;
                                            else
                                                trade.p1b= algo.tasEngine.firstLeg.lastTradedPrice - 10;
                                        }
                                    }

                                    if (trade.reset == false)
                                    {
                                        trade.order1b.Price = trade.p1b;
                                        algo.omsEngine.tradingManager.SendNewOrder(trade.order1b);
                                    }
                                    else
                                    {
                                        trade.order1b.Price = trade.p1b;
                                        algo.omsEngine.tradingManager.ModifyOrder(trade.order1b);
                                        while (trade.order1b.Status != Order.OrderStatus.Replace)
                                        {
                                            Thread.Sleep(0);
                                            if (trade.order1b.filledQuantity == 1)
                                            {
                                                trade.order1b.Status = Order.OrderStatus.Fill;
                                                trade.status = 3;
                                                break;
                                            }
                                        }
                                        trade.reset = false;
                                    }
                                }
                                else
                                {
                                    trade.status = 2;
                                    System.Diagnostics.Trace.WriteLine("MBX Update: Initiating" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());
                                }
                                #endregion
                            }
                            else //sell
                            {
                                #region SELL

                                if (trade.order1s.filledQuantity > 0)
                                {
                                    trade.order1s.Status = Order.OrderStatus.Fill;
                                    trade.status = 3;
                                    continue;
                                }

                                if (trade.order1s.Status == Order.OrderStatus.PendingNew || trade.reset)
                                {
                                    dtemp1 = algo.GetClosestM50(algo.tasEngine.firstLeg.lastTradedPrice);
                                    dtemp2 = algo.tasEngine.firstLeg.lastTradedPrice - dtemp1;

                                    betemp1 = algo.tasEngine.firstLeg.getBOLL(60);
                                    ohlctemp1 = algo.tasEngine.firstLeg.getOHLC(60);

                                    if (betemp1.UpperLevel > 0)
                                    {
                                        Console.WriteLine(betemp1.UpperLevel);
                                    }

                                    if (dtemp2 < 0 && dtemp2 > -10) // if closest50 is less than 10 ticks above ltp
                                    {
                                        trade.p1s = dtemp1 - 2;
                                    }
                                    else
                                    {
                                        if (betemp1.MiddleLevel > algo.tasEngine.firstLeg.lastTradedPrice) // if ltp is in lower band
                                        {
                                            if ((betemp1.MiddleLevel - algo.tasEngine.firstLeg.lastTradedPrice) < 10)
                                                trade.p1s = betemp1.MiddleLevel - 2;
                                            else
                                                trade.p1s = algo.tasEngine.firstLeg.lastTradedPrice + 10;
                                        }
                                        else // if ltp is in upper band
                                        {
                                            if ((betemp1.UpperLevel - algo.tasEngine.firstLeg.lastTradedPrice) < 10)
                                                trade.p1s = betemp1.UpperLevel - 2;
                                            else
                                                trade.p1s = algo.tasEngine.firstLeg.lastTradedPrice + 10;
                                        }
                                    }

                                    if (trade.reset == false)
                                    {
                                        trade.order1s.Price = trade.p1s;
                                        algo.omsEngine.tradingManager.SendNewOrder(trade.order1s);
                                    }
                                    else
                                    {
                                        trade.order1s.Price = trade.p1s;
                                        algo.omsEngine.tradingManager.ModifyOrder(trade.order1s);

                                        while (trade.order1s.Status != Order.OrderStatus.Replace)
                                        {
                                            Thread.Sleep(0);
                                            if (trade.order1s.filledQuantity == 1)
                                            {
                                                trade.order1s.Status = Order.OrderStatus.Fill;
                                                trade.status = 3;
                                                break;
                                            }
                                        }

                                        trade.reset = false;
                                    }

                                }                                
                                else
                                {
                                    trade.status = 2;
                                    System.Diagnostics.Trace.WriteLine("MBX Update: Initiating" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());

                                }
                                #endregion
                            }                        
                            #endregion
                        }
                        if (trade.status == 2)
                        {
                            #region FIRST ORDER PLACED
                            // orders placed and working.
                            // check if all orders are still working. 
                            // if yes, modify / monitor. if no, set initiate leg, unhedged quantities and change status to 3
                            createdAge = DateTime.Now.Subtract(trade.createTime);
                            // Trade initiated 
                            if (trade.initiateSide == 1)
                            {
                                #region BUY

                                if (trade.order1b.filledQuantity > 0)
                                {
                                    trade.order1b.Status = Order.OrderStatus.Fill;
                                    trade.status = 3;
                                    continue;
                                }

                                trade.order1b.workingAge = DateTime.Now.Subtract(trade.order1b.TransactTime).TotalMilliseconds;

                                if (trade.order1b.workingAge > 5000 && (trade.order1b.Status == Order.OrderStatus.New || trade.order1b.Status == Order.OrderStatus.Replace))
                                {
                                    if ((algo.tasEngine.firstLeg.lastTradedPrice - trade.order1b.Price) > 10)
                                    {
                                        trade.reset = true;
                                        trade.status = 1;
                                        continue;
                                    }
                                }

                                if (trade.order1b.Status == Order.OrderStatus.Fill)
                                {
                                    trade.status = 3;
                                    trade.initiateTime = DateTime.Now;
                                    System.Diagnostics.Trace.WriteLine("MBX Update: Initiated" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());

                                }
                                #endregion
                            }
                            else if (trade.initiateSide == 2)
                            {
                                #region SELL
                                if (trade.order1s.filledQuantity > 0)
                                {
                                    trade.order1s.Status = Order.OrderStatus.Fill;
                                    trade.status = 3;
                                    continue;
                                }

                                trade.order1s.workingAge = DateTime.Now.Subtract(trade.order1s.TransactTime).TotalMilliseconds;

                                if (trade.order1s.workingAge > 5000 && trade.order1s.Status == Order.OrderStatus.New)
                                {
                                    if ((trade.order1b.Price - algo.tasEngine.firstLeg.lastTradedPrice) > 20)
                                    {
                                        trade.reset = true;
                                        trade.status = 1;
                                        continue;
                                    }
                                }

                                if ((trade.order1s.Status == Order.OrderStatus.PartialFill || trade.order1s.Status == Order.OrderStatus.Fill))
                                {
                                    trade.status = 3;
                                    trade.initiateTime = DateTime.Now;
                                    System.Diagnostics.Trace.WriteLine("MBX Update: Initiated" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());
                                }
                                #endregion
                            }
                            #endregion
                        }
                        if (trade.status == 3)
                        {
                            #region PLACE SECOND ORDER

                            Thread.Sleep(0);

                            // first leg initiated. place exit order 
                            // read market data. if slippage happens set status to 4                            
                                                        
                            if (trade.initiateSide == 1)
                            {
                                #region BUY

                                if (trade.order1s.filledQuantity > 0 && trade.order1s.Status != Order.OrderStatus.Fill)
                                {
                                    trade.order1s.Status = Order.OrderStatus.Fill;
                                }

                                if (trade.order1bb.Status != Order.OrderStatus.Canceled && trade.order1bb.Status != Order.OrderStatus.PendingNew && trade.order1bb.filledQuantity == 0)
                                {
                                    algo.omsEngine.tradingManager.CancelOrder(trade.order1bb);
                                    while (trade.order1bb.Status != Order.OrderStatus.Canceled)
                                    {
                                        Thread.Sleep(0);
                                        if (trade.order1bb.filledQuantity == 1 && trade.order1bb.filledQuantity == trade.order1bb.quantity)
                                        {
                                            trade.order1bb.Status = Order.OrderStatus.Fill;
                                            trade.status = 4;
                                            break;
                                        }
                                        else if (trade.order1bb.filledQuantity == 1 && trade.order1bb.filledQuantity < trade.order1bb.quantity)
                                        {
                                            trade.order1bb.Status = Order.OrderStatus.PartialFill;
                                            trade.status = 4;
                                            break;
                                        }

                                    }
                                }
                                
                                if (trade.order1bb.Status == Order.OrderStatus.Fill || trade.order1bb.Status == Order.OrderStatus.PartialFill)
                                {
                                    if (trade.order1bb.filledQuantity != trade.order1ss.filledQuantity)
                                    {
                                        trade.status = 4;
                                        continue;
                                    }
                                }
                                
                                if (trade.order1s.Status != Order.OrderStatus.New && trade.order1s.Status != Order.OrderStatus.Fill && trade.order1s.Status != Order.OrderStatus.Replace) // check if status should be new or pendingnew
                                {
                                    trade.p1s = trade.order1b.LastFillPrice + 3;
                                    trade.order1s.Price = trade.p1s;
                                    algo.omsEngine.tradingManager.SendNewOrder(trade.order1s);
                                }                                
                                else if (trade.order1s.Status == Order.OrderStatus.Fill)
                                {
                                    if ((trade.order1bb.Status == Order.OrderStatus.PendingNew && trade.order1ss.Status == Order.OrderStatus.PendingNew)
                                        || ((trade.order1bb.filledQuantity == trade.order1ss.filledQuantity)
                                        && ((trade.order1bb.Status == Order.OrderStatus.Fill && trade.order1ss.Status == Order.OrderStatus.Fill)
                                        || (trade.order1bb.Status == Order.OrderStatus.Canceled && trade.order1ss.Status == Order.OrderStatus.Canceled)
                                        || (trade.order1bb.Status == Order.OrderStatus.PartialFill && trade.order1ss.Status == Order.OrderStatus.PartialFill))))
                                    {
                                        trade.status = 5;
                                        System.Diagnostics.Trace.WriteLine("MBX Update: Completed" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());
                                        //continue;
                                    }
                                    else if (trade.order1bb.filledQuantity != trade.order1ss.filledQuantity)
                                    {
                                        trade.status = 4;
                                        continue;
                                    }

                                }
                                else if (trade.order1s.Status == Order.OrderStatus.New || trade.order1s.Status == Order.OrderStatus.PartialFill)
                                {
                                    if ((algo.tasEngine.firstLeg.lastTradedPrice - trade.order1b.lastFillPrice) < -5)
                                    {
                                        trade.status = 4;
                                        System.Diagnostics.Trace.WriteLine("MBX Update: Slippage" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());
                                    }
                                }

                                #endregion
                            }
                            else if (trade.initiateSide == 2)
                            {
                                #region SELL
                                if (trade.order1b.filledQuantity > 0)
                                {
                                    trade.order1b.Status = Order.OrderStatus.Fill;
                                }
                               
                                if (trade.order1ss.Status != Order.OrderStatus.Canceled && trade.order1ss.Status != Order.OrderStatus.PendingNew)
                                {
                                    algo.omsEngine.tradingManager.CancelOrder(trade.order1ss);
                                    while (trade.order1ss.Status != Order.OrderStatus.Canceled)
                                    {
                                        Thread.Sleep(0);
                                        if (trade.order1ss.filledQuantity == 1)
                                        {
                                            trade.order1ss.Status = Order.OrderStatus.Fill;
                                            trade.status = 4;
                                            break;
                                        }
                                    }
                                }
                                if (trade.order1ss.Status == Order.OrderStatus.Fill || trade.order1ss.Status == Order.OrderStatus.PartialFill)
                                {
                                    trade.status = 4;
                                    continue;
                                }
                                
                                if (trade.order1b.Status != Order.OrderStatus.New && trade.order1b.Status != Order.OrderStatus.Fill)
                                {
                                    trade.p1b= trade.order1s.lastFillPrice - 3;
                                    trade.order1b.Price = trade.p1b;
                                    algo.omsEngine.tradingManager.SendNewOrder(trade.order1b);
                                }
                                else if (trade.order1b.Status == Order.OrderStatus.Fill)
                                {
                                    trade.status = 5;
                                    System.Diagnostics.Trace.WriteLine("MBX Update: Completed" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());
                                }
                                else if (trade.order1b.Status == Order.OrderStatus.New || trade.order1b.Status == Order.OrderStatus.PartialFill)
                                {
                                    if ((algo.tasEngine.firstLeg.lastTradedPrice - trade.order1s.lastFillPrice) > 5)
                                    {
                                        trade.status = 4;
                                        System.Diagnostics.Trace.WriteLine("MBX Update: Slippage" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());
                                    }
                                }
                                #endregion
                            }
                            #endregion
                        }
                        if (trade.status == 4) // Slippage happened - double up and exit
                        {
                            #region SLIPPAGE

                            Thread.Sleep(0);
                            initiatedAge = DateTime.Now.Subtract(trade.initiateTime);

                            if (trade.initiateSide == 1)
                            {
                                #region BUY
                                if (trade.order1s.Status == Order.OrderStatus.Fill
                                    && (trade.order1bb.filledQuantity == 0)
                                    && (trade.order1ss.filledQuantity == 0))
                                {
                                    if (trade.order1bb.Status != Order.OrderStatus.PendingNew)
                                    {
                                        algo.omsEngine.tradingManager.CancelOrder(trade.order1bb);
                                        while (trade.order1bb.Status != Order.OrderStatus.Canceled || trade.order1bb.filledQuantity !=0)
                                        {
                                            Thread.Sleep(0);
                                            if (trade.order1bb.filledQuantity > 0)
                                            {
                                                trade.order1bb.Status = Order.OrderStatus.Fill;
                                                break;
                                            }
                                        }
                                    }

                                    if (trade.order1ss.Status != Order.OrderStatus.PendingNew)
                                    {
                                        algo.omsEngine.tradingManager.CancelOrder(trade.order1ss);
                                        while (trade.order1ss.Status != Order.OrderStatus.Canceled)
                                        {
                                            Thread.Sleep(0);
                                            if (trade.order1ss.filledQuantity == 1)
                                            {
                                                trade.order1ss.Status = Order.OrderStatus.Fill;
                                                break;
                                            }
                                        }
                                    }

                                    if ((trade.order1bb.Status == Order.OrderStatus.PendingNew || trade.order1bb.Status == Order.OrderStatus.Canceled)
                                        && (trade.order1ss.Status == Order.OrderStatus.PendingNew || trade.order1ss.Status == Order.OrderStatus.Canceled)
                                        && trade.order1s.Status == Order.OrderStatus.Fill)
                                    {
                                        trade.status = 5;
                                        System.Diagnostics.Trace.WriteLine("MBX Update: Completed" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());
                                        continue;
                                    }

                                }

                                if (trade.order1bb.Status == Order.OrderStatus.Canceled || (trade.order1bb.Status == Order.OrderStatus.Fill && trade.order1ss.Status == Order.OrderStatus.Fill))
                                    trade.order1bb = algo.CreateOrder(trade.tradeID, trade.legOne, 1, Order.OrderType.Limit);
                                if (trade.order1ss.Status == Order.OrderStatus.Canceled || (trade.order1bb.Status == Order.OrderStatus.Fill && trade.order1ss.Status == Order.OrderStatus.Fill) || (trade.order1bb.Status == Order.OrderStatus.PendingNew && trade.order1ss.Status == Order.OrderStatus.Fill))
                                    trade.order1ss = algo.CreateOrder(trade.tradeID, 1, trade.legOne, Order.OrderType.Limit);


                                if (trade.order1bb.Status != Order.OrderStatus.New && trade.order1bb.filledQuantity < 1)
                                {
                                    lock (algo.tasEngine.firstLeg.rwLock)
                                    {
                                       // System.Diagnostics.Trace.WriteLine("MBX Update: DBG READING : " + algo.tasEngine.firstLeg.ID + " : " + algo.tasEngine.firstLeg.Desc + " : " + algo.tasEngine.firstLeg.lastTradedPrice.ToString());

                                        if ((algo.tasEngine.firstLeg.lastTradedPrice - trade.order1b.lastFillPrice) <= -10)
                                        {
                                            trade.order1bb.quantity = 2;
                                            trade.p1bb = trade.order1b.lastFillPrice - 10;
                                        }
                                        else if ((algo.tasEngine.firstLeg.lastTradedPrice - trade.order1b.lastFillPrice) <= -5)
                                        {
                                            trade.p1bb = trade.order1b.lastFillPrice - 5;
                                        }
                                        else
                                        {
                                            trade.status = 3;
                                            System.Diagnostics.Trace.WriteLine("MBX Update: Slippage Retraced" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());
                                            continue;
                                        }

                                        trade.order1bb.Price = trade.p1bb;
                                        algo.omsEngine.tradingManager.SendNewOrder(trade.order1bb);
                                    }

                                }
                                else if (trade.order1bb.Status == Order.OrderStatus.PartialFill)
                                {
                                    trade.order1ss.quantity = trade.order1bb.filledQuantity - trade.order1ss.filledQuantity;
                                    trade.p1ss = trade.order1bb.lastFillPrice + 5;
                                    if (trade.order1s.Status != Order.OrderStatus.Replace)
                                        trade.p1s = trade.p1ss + 1;

                                    if (trade.order1s.Price != trade.p1s)
                                    {
                                        algo.omsEngine.tradingManager.ModifyOrder(trade.order1s);

                                        while (trade.order1s.Status != Order.OrderStatus.Replace)
                                        {
                                            Thread.Sleep(0);
                                            if (trade.order1s.filledQuantity == 1)
                                            {
                                                trade.order1s.Status = Order.OrderStatus.Fill;
                                                break;
                                            }
                                        }
                                    }

                                    if (trade.order1ss.Status == Order.OrderStatus.PendingNew)
                                    {
                                        trade.order1ss.Price = trade.p1ss;
                                        algo.omsEngine.tradingManager.SendNewOrder(trade.order1ss);
                                    }

                                }
                                else if (trade.order1bb.Status == Order.OrderStatus.Fill && trade.order1ss.filledQuantity != trade.order1bb.filledQuantity)
                                {
                                    if (trade.order1ss.Status == Order.OrderStatus.PendingNew)
                                    {
                                        trade.order1ss.quantity = trade.order1bb.filledQuantity - trade.order1ss.filledQuantity;
                                        trade.p1ss = trade.order1bb.lastFillPrice + 5;
                                        if (trade.order1s.Status != Order.OrderStatus.Replace)
                                            trade.p1s = trade.order1ss.Price + 1;

                                        trade.order1ss.Price = trade.p1ss;
                                        algo.omsEngine.tradingManager.SendNewOrder(trade.order1ss);
                                        if (trade.order1s.Price != trade.p1s)
                                        {
                                            algo.omsEngine.tradingManager.ModifyOrder(trade.order1s);

                                            while (trade.order1s.Status != Order.OrderStatus.Replace)
                                            {
                                                Thread.Sleep(0);
                                                if (trade.order1s.filledQuantity == 1)
                                                {
                                                    trade.order1s.Status = Order.OrderStatus.Fill;
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                    else if (trade.order1ss.Status == Order.OrderStatus.New || trade.order1ss.quantity != trade.order1bb.filledQuantity || trade.order1ss.Price != (trade.order1bb.lastFillPrice + 5))
                                    {
                                        trade.order1ss.quantity = trade.order1bb.filledQuantity - trade.order1ss.filledQuantity;
                                        trade.p1ss = trade.order1bb.lastFillPrice + 5;

                                        if (trade.order1ss.Price != trade.p1ss)
                                        {
                                            algo.omsEngine.tradingManager.ModifyOrder(trade.order1ss);
                                            while (trade.order1ss.Status != Order.OrderStatus.Replace)
                                            {
                                                Thread.Sleep(0);
                                                if (trade.order1ss.filledQuantity == 1)
                                                {
                                                    trade.order1ss.Status = Order.OrderStatus.Fill;
                                                    break;
                                                }
                                            }
                                        }
                                        if (trade.order1s.Price != (trade.order1ss.Price + 1) && trade.order1s.Status != Order.OrderStatus.Replace)
                                        {
                                            trade.order1s.Price = trade.order1ss.Price + 1;
                                            algo.omsEngine.tradingManager.ModifyOrder(trade.order1s);

                                            while (trade.order1s.Status != Order.OrderStatus.Replace)
                                            {
                                                Thread.Sleep(0);
                                                if (trade.order1s.filledQuantity == 1)
                                                {
                                                    trade.order1s.Status = Order.OrderStatus.Fill;
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                }
                                
                                if(trade.order1ss.filledQuantity == trade.order1bb.filledQuantity && trade.order1s.filledQuantity == 0 && trade.order1ss.Status == Order.OrderStatus.Fill)
                                {
                                    if ((algo.tasEngine.firstLeg.lastTradedPrice - trade.order1b.lastFillPrice) >= -5)
                                    {
                                        trade.status = 3;
                                        System.Diagnostics.Trace.WriteLine("MBX Update: Slippage Retraced" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());
                                        continue;
                                    }

                                    // write code to convert it to status 3 based on ohlc and boll levels - trade reset
                                    //System.Diagnostics.Trace.WriteLine("MBX Update: Initiated" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());
                                    
                                }
                                if (trade.order1ss.filledQuantity == trade.order1bb.filledQuantity && trade.order1s.Status == Order.OrderStatus.Fill && trade.order1ss.Status == Order.OrderStatus.Fill)
                                {
                                    trade.status = 5;
                                    System.Diagnostics.Trace.WriteLine("MBX Update: Completed" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());
                                    continue;
                                }

                              //  if(trade.order1b.Price > dtemp1

                                if (trade.order1bb.Status == Order.OrderStatus.New)
                                {
                                    if ((algo.tasEngine.firstLeg.lastTradedPrice - trade.order1b.lastFillPrice) > 2 || trade.order1s.Status == Order.OrderStatus.Fill)
                                    {
                                        // check the next line
                                        if (trade.order1bb.Status != Order.OrderStatus.Canceled && trade.order1bb.Status != Order.OrderStatus.PendingCancel)
                                        {
                                            algo.omsEngine.tradingManager.CancelOrder(trade.order1bb);
                                            while (trade.order1bb.Status != Order.OrderStatus.Canceled)
                                            {
                                                Thread.Sleep(0);
                                                if (trade.order1bb.filledQuantity == 1)
                                                {
                                                    trade.order1bb.Status = Order.OrderStatus.Fill;
                                                    trade.status = 4;
                                                    break;
                                                }
                                            }
                                        }

                                        if (trade.order1bb.Status == Order.OrderStatus.Canceled)
                                        {
                                            trade.status = 3;
                                            continue;
                                        }
                                    }
                                }
                                #endregion
                            }
                            else if (trade.initiateSide == 2)
                            {
                                #region SELL
                                if (trade.order1b.Status == Order.OrderStatus.Fill
                                    && (trade.order1ss.filledQuantity == 0)
                                    && (trade.order1bb.filledQuantity == 0))
                                {
                                    if (trade.order1ss.Status != Order.OrderStatus.PendingNew)
                                        algo.omsEngine.tradingManager.CancelOrder(trade.order1ss);
                                    {
                                        while (trade.order1ss.Status != Order.OrderStatus.Canceled)
                                        {
                                            Thread.Sleep(0);
                                            if (trade.order1ss.filledQuantity == 1)
                                            {
                                                trade.order1ss.Status = Order.OrderStatus.Fill;
                                                trade.status = 4;
                                                break;
                                            }
                                        }
                                    }

                                    if (trade.order1bb.Status != Order.OrderStatus.PendingNew)
                                    {
                                        algo.omsEngine.tradingManager.CancelOrder(trade.order1bb);
                                        while (trade.order1bb.Status != Order.OrderStatus.Canceled)
                                        {
                                            Thread.Sleep(0);
                                            if (trade.order1bb.filledQuantity == 1)
                                            {
                                                trade.order1bb.Status = Order.OrderStatus.Fill;
                                                trade.status = 4;
                                                break;
                                            }
                                        }
                                    }

                                    while ((trade.order1ss.Status != Order.OrderStatus.PendingNew && trade.order1ss.Status != Order.OrderStatus.Canceled)
                                        || (trade.order1bb.Status != Order.OrderStatus.PendingNew && trade.order1bb.Status != Order.OrderStatus.Canceled))
                                    {
                                        Thread.Sleep(0);
                                        if (trade.order1ss.filledQuantity > 0 || trade.order1bb.filledQuantity > 0)
                                            break;
                                    }

                                    if ((trade.order1ss.Status == Order.OrderStatus.PendingNew || trade.order1ss.Status == Order.OrderStatus.Canceled)
                                        && (trade.order1bb.Status == Order.OrderStatus.PendingNew || trade.order1bb.Status == Order.OrderStatus.Canceled))
                                    {
                                        trade.status = 5;
                                        System.Diagnostics.Trace.WriteLine("MBX Update: Completed" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());
                                        continue;
                                    }

                                }

                                if (trade.order1ss.Status == Order.OrderStatus.Canceled)
                                    trade.order1ss = algo.CreateOrder(trade.tradeID, trade.legOne, 1, Order.OrderType.Limit);
                                if (trade.order1bb.Status == Order.OrderStatus.Canceled)
                                    trade.order1bb = algo.CreateOrder(trade.tradeID, 1, trade.legOne, Order.OrderType.Limit);
                                

                                if (trade.order1ss.Status != Order.OrderStatus.New && trade.order1ss.filledQuantity < 1)
                                {
                                    if ((algo.tasEngine.firstLeg.lastTradedPrice - trade.order1s.lastFillPrice) >= 10)
                                    {
                                        trade.order1ss.quantity = 2;
                                        trade.p1ss = (long)algo.tasEngine.firstLeg.bestBid.Price;
                                    }
                                    else if ((algo.tasEngine.firstLeg.lastTradedPrice - trade.order1b.lastFillPrice) >= 5)
                                    {
                                        trade.p1ss = (long)algo.tasEngine.firstLeg.bestAsk.Price + 1;
                                    }


                                    if (trade.order1ss.Status != Order.OrderStatus.New && trade.order1ss.filledQuantity < 1) // check if it should be new or pending new
                                    {
                                        trade.order1ss.Price = trade.p1ss;
                                        algo.omsEngine.tradingManager.SendNewOrder(trade.order1ss);
                                    }
                                }
                                else if (trade.order1ss.Status == Order.OrderStatus.PartialFill)
                                {
                                    trade.order1bb.quantity = trade.order1ss.filledQuantity - trade.order1bb.filledQuantity;
                                    trade.p1bb = trade.order1ss.lastFillPrice - 5;
                                    trade.p1b = trade.p1bb - 1;

                                    if (trade.order1b.Price != trade.p1b)
                                    {
                                        algo.omsEngine.tradingManager.ModifyOrder(trade.order1b);

                                        while (trade.order1b.Status != Order.OrderStatus.Replace)
                                        {
                                            Thread.Sleep(0);
                                            if (trade.order1b.filledQuantity == 1)
                                            {
                                                trade.order1b.Status = Order.OrderStatus.Fill;
                                                break;
                                            }
                                        }
                                    }
                                    if (trade.order1bb.Status == Order.OrderStatus.PendingNew)
                                    {
                                        trade.order1bb.Price = trade.p1bb;
                                        algo.omsEngine.tradingManager.SendNewOrder(trade.order1bb);
                                    }

                                }
                                else if (trade.order1ss.Status == Order.OrderStatus.Fill && trade.order1bb.filledQuantity != trade.order1ss.filledQuantity)
                                {
                                    if (trade.order1bb.Status == Order.OrderStatus.PendingNew)
                                    {
                                        trade.order1bb.quantity = trade.order1ss.filledQuantity - trade.order1bb.filledQuantity;
                                        trade.p1bb = trade.order1ss.lastFillPrice - 5;
                                        trade.p1b = trade.order1bb.Price - 1;
                                        trade.order1bb.Price = trade.p1bb;
                                        algo.omsEngine.tradingManager.SendNewOrder(trade.order1bb);
                                        if (trade.order1b.Price != trade.p1b)
                                        {
                                            algo.omsEngine.tradingManager.ModifyOrder(trade.order1b);

                                            while (trade.order1b.Status != Order.OrderStatus.Replace)
                                            {
                                                Thread.Sleep(0);
                                                if (trade.order1b.filledQuantity == 1)
                                                {
                                                    trade.order1b.Status = Order.OrderStatus.Fill;
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                    else if (trade.order1bb.Status == Order.OrderStatus.New || trade.order1bb.quantity != trade.order1ss.filledQuantity || trade.order1bb.Price != (trade.order1ss.lastFillPrice - 5))
                                    {
                                        trade.order1bb.quantity = trade.order1ss.filledQuantity - trade.order1bb.filledQuantity;
                                        trade.p1bb = trade.order1ss.lastFillPrice - 5;

                                        if (trade.order1bb.Price != trade.p1bb)
                                        {
                                            algo.omsEngine.tradingManager.ModifyOrder(trade.order1bb);

                                            while (trade.order1bb.Status != Order.OrderStatus.Replace)
                                            {
                                                Thread.Sleep(0);
                                                if (trade.order1bb.filledQuantity == 1)
                                                {
                                                    trade.order1bb.Status = Order.OrderStatus.Fill;
                                                    break;
                                                }
                                            }
                                        }
                                        if (trade.order1b.Price != (trade.order1bb.Price - 1))
                                        {
                                            trade.order1b.Price = trade.order1bb.Price - 1;
                                            algo.omsEngine.tradingManager.ModifyOrder(trade.order1b);
                                            while (trade.order1b.Status != Order.OrderStatus.Replace)
                                            {
                                                Thread.Sleep(0);
                                                if (trade.order1b.filledQuantity == 1)
                                                {
                                                    trade.order1b.Status = Order.OrderStatus.Fill;
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                }

                                if (trade.order1bb.filledQuantity == trade.order1ss.filledQuantity && trade.order1b.filledQuantity == 0)
                                {
                                    // write code to convert it to status 3 based on ohlc and boll levels - trade reset
                                    //System.Diagnostics.Trace.WriteLine("MBX Update: Initiated" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());

                                }
                                if (trade.order1bb.filledQuantity == trade.order1ss.filledQuantity && trade.order1b.Status == Order.OrderStatus.Fill)
                                {
                                    // write code to convert it to status 3 based on ohlc and boll levels - trade reset
                                    trade.status = 5;
                                    System.Diagnostics.Trace.WriteLine("MBX Update: Completed" + ";" + trade.tradeID + ";" + trade.status + ";" + DateTime.Now + ";" + trade.tradeType + ";" + trade.initiateQuantity + ";" + trade.initiateLeg + ";" + trade.initiateSide + ";" + trade.ToString());

                                }

                                if (trade.order1ss.Status == Order.OrderStatus.New)
                                {
                                    if ((algo.tasEngine.firstLeg.lastTradedPrice - trade.order1s.lastFillPrice) < 2 || trade.order1b.Status == Order.OrderStatus.Fill)
                                    {
                                        // check the next line
                                        if (trade.order1ss.Status != Order.OrderStatus.Canceled && trade.order1ss.Status != Order.OrderStatus.PendingCancel)
                                        {
                                            algo.omsEngine.tradingManager.CancelOrder(trade.order1ss);
                                            while (trade.order1ss.Status != Order.OrderStatus.Canceled)
                                            {
                                                Thread.Sleep(0);
                                                if (trade.order1ss.filledQuantity == 1)
                                                {
                                                    trade.order1ss.Status = Order.OrderStatus.Fill;
                                                    trade.status = 4;
                                                    break;
                                                }
                                            }
                                        }
                                        if (trade.order1ss.Status == Order.OrderStatus.Canceled)
                                            trade.status = 3;
                                    }
                                }

                                #endregion
                            }
                            #endregion
                        }
                        if (trade.status == 5)
                        {
                            #region TRADE CLOSURE
                            // trade closed. exit the loops and the thread
                            // remove the Trade and its corresponding orders from the current list and add them to closed list
                            args.algo.sMMTradeBook.Remove(trade);
                            args.algo.tradeBookClosed.Add(trade);
                            algo.tradeCreated = false;
                            break;
                            #endregion
                        }
                        if (trade.status == 7)
                        {
                            #region TRADE CANCELLED
                            // trade cancelled. exit the loops and the thread
                            // remove the Trade and its corresponding orders from the current list and add them to closed list
                            args.algo.sMMTradeBook.Remove(trade);
                            args.algo.tradeBookCancelled.Add(trade);
                            algo.tradeCreated = false;
                            break;
                            #endregion
                        }
                        #endregion
                    }
                    

                    else if (trade.tradeType == 3)
                    #region
                    {
                        // for trade type 3, do the following
                        if (trade.status == 1)
                        {
                            // trade is newly generated. create orders here. place orders. if orders are accepted change status to 2
                            if (trade.initiateSide == 1) // buy
                            {
                                //placing limit order
                                Order.OrderType ordertype = Order.OrderType.Limit;
                                Order.TimeInForce tif = Order.TimeInForce.Day;
                                double price;
                                price = trade.ticks; // add the book.bestbid of second security ID and the spread
                                string sid = "CLM2";
                                //trade.order1b = args.algo.CreateOrder(trade.tradeID, sid, trade.initiateQuantity, ordertype, tif);
                                
                            }
                            else //sell
                            {

                            }
                        }
                        if (trade.status == 2)
                        {
                            // orders placed and working.
                            // check if all orders are still working. 
                            // if yes, modify / monitor. if no, set initiate leg, unhedged quantities and change status to 3
                            // handle partially filled orders.
                        }
                        if (trade.status == 3)
                        {
                            // first leg initiated. place market order for second and third leg
                            // read market data. if slippage happens set status to 4

                        }
                        if (trade.status == 4)
                        {
                            // if slippage happens, convert trade to type 1, 2 or 4 and handle.
                            // first leg initiated. slippage occured on second leg
                            // consider changing type from type 5 to type 1 or 4.
                        }
                        if (trade.status == 5)
                        {
                            // trade closed. exit the loops and the thread
                            // remove the Trade and its corresponding orders from the current list and add them to closed list
                            args.algo.sprMMTradeBook.Remove(trade);
                            args.algo.tradeBookClosed.Add(trade);
                            break;
                        }
                        if (trade.status == 7)
                        {
                            // trade cancelled. exit the loops and the thread
                            // remove the Trade and its corresponding orders from the current list and add them to closed list
                            args.algo.sprMMTradeBook.Remove(trade);
                            args.algo.tradeBookCancelled.Add(trade);
                            break;
                        }
                    }
                    #endregion

                    else if (trade.tradeType == 4)
                    #region
                    {
                        // for trade type 4, do the following
                        if (trade.status == 1)
                        {
                            // trade is newly generated. create orders here. place orders. if orders are accepted change status to 2
                            if (trade.initiateSide == 1) // buy
                            {
                                //placing limit order
                                Order.OrderType ordertype = Order.OrderType.Limit;
                                Order.TimeInForce tif = Order.TimeInForce.Day;
                                double price;
                                price = trade.ticks; // add the book.bestbid of second security ID and the spread
                                string sid = "CLX2";
                                //trade.order1b = args.algo.CreateOrder(trade.tradeID, sid, trade.initiateQuantity, ordertype, tif);
                                
                            }
                            else //sell
                            {

                            }
                        }
                        if (trade.status == 2)
                        {
                            // orders placed and working.
                            // check if all orders are still working. 
                            // if yes, modify / monitor. if no, set initiate leg, unhedged quantities and change status to 3
                            // handle partially filled orders.
                        }
                        if (trade.status == 3)
                        {
                            // first leg initiated. place market order for second and third leg
                            // read market data. if slippage happens set status to 4

                        }
                        if (trade.status == 4)
                        {
                            // if slippage happens, convert trade to type 1, 2 or 4 and handle.
                            // first leg initiated. slippage occured on second leg
                            // consider changing type from type 5 to type 1 or 4.
                        }
                        if (trade.status == 5)
                        {
                            // trade closed. exit the loops and the thread
                            // remove the Trade and its corresponding orders from the current list and add them to closed list
                            args.algo.fsSprTradeBook.Remove(trade);
                            args.algo.tradeBookClosed.Add(trade);
                            break;
                        }
                        if (trade.status == 7)
                        {
                            // trade cancelled. exit the loops and the thread
                            // remove the Trade and its corresponding orders from the current list and add them to closed list
                            args.algo.fsSprTradeBook.Remove(trade);
                            args.algo.tradeBookCancelled.Add(trade);
                            break;
                        }
                    }
                    #endregion
                }
               
            }

            catch (Exception ex)
            {
                Console.WriteLine("Exception" + ex.ToString());
            }
           
        }

        private long GetClosestM50(double p)
        {
            long M50;
            int temp1, temp2;

            temp1 = (int)p;
            temp2 = temp1 / 50 * 50;
            M50 = (long)temp2;

            if ((p - M50) >= 25)
                M50 = M50 + 50;

            return M50;
        }

        private void ReadTASData()
        {
            OHLCEntity ohlc = new OHLCEntity();
            BollingerEntity boll = new BollingerEntity();

            ohlc = tasEngine.ReadData("CLX2", 10); // securityID, Time Interval - returns ohlc
            boll = tasEngine.ReadData(10, "CLX2"); // Time Interval, SecurityID - returns bollinger           
        }

        [MTAThread]
        private void ProcessOMSData()
        {
            while (exitStatusProcessingThread == false)
            {
                omsInterruptEvent.WaitOne();
                omsInterruptEvent.Reset();

                lock (orderQueue)
                {
                    foreach (Order order in orderQueue)
                    {
                        if (order.Status == Order.OrderStatus.Expired)
                        {
                            System.Diagnostics.Trace.WriteLine("MBX Update: Expired Order : " + order.SecurityID + ", Quantity :" + order.Quantity + ", Price :" + order.Price);
                        }
                        else
                        {
                            System.Diagnostics.Trace.WriteLine("MBX Update: Executed Order : " + order.SecurityID + ", Quantity :" + order.Quantity + ", Price :" + order.Price);
                        }
                    }
                }
            }
        }
    }
}
